之前寫博客不深動,只搭個架子,像作筆記,沒有本身的思考,也沒什麼人來看。這個毛病得改,就從這一篇開始…html
最近準備面試,深感基礎之重要,奈何我不是計算機科班出身,基礎方面有些捉襟見肘。短時間怎麼補?作面實題唄。遇到哪兒沒理解透,本身查資料,印象深入。這個問題就是這麼來的。原題很簡單:「對於方法,參數傳遞分爲值傳遞和____兩種。」這還不簡單,但我得拓展啊,得思考啊…面試
如下一、2是個人意淫,但記錄本身的一些錯誤想法並思考改正仍是有益處的,但願不會對你們有誤導。以爲麻煩的話能夠直接看3。ide
一、什麼是值傳遞和引用傳遞?idea
我一開始的理解是,值類型根本沒有引用啊,它能有引用傳遞?它的值傳遞和引用傳遞應該是同樣的。至於引用類型,它的值傳遞應該是一個深拷貝,引用傳遞應該是一個淺拷貝。對於這一類比,最初還頗感得意。但查資料才知道,What a stupid idea!沒辦法,非科班出身,知識不成體系,有盲點,但我知道這不是藉口,這不在大補嘛,補得跟小雞子似的。spa
看了http://www.cnblogs.com/whc-blog/archive/2011/07/20/2111803.html這篇,感性的知道了什麼是值傳遞和引用傳遞。其實也不是壓根不知道,長時間不用忘了,而後就出現了上面離奇的想法。code
其實在整個思考完了之後我給值傳遞和引用傳遞下了個定義,在這裏先搬出來:(歡迎你們批評指正)htm
值傳遞是傳遞棧中的值;引用傳遞是傳遞棧地址。對象
二、引用類型的值傳遞和引用傳遞能夠類比成深拷貝和淺拷貝嗎?blog
到此對於這個問題仍是有疑問的,就寫了個小Demoget
class Program { static void Main(string[] args) { Student xiaohong = new Student("小紅", 12); BanZheng(ref xiaohong); //BanJiaZheng(xiaohong); Console.WriteLine(xiaohong.Name + " " + xiaohong.Age); Console.ReadKey(); } //辦證 static void BanZheng(ref Student student) { student.Name = "紅姐"; student.Age = 18; } //辦假證 static void BanJiaZheng(Student student) { student.Name = "紅姐"; student.Age = 18; } } class Student { public Student(string name, int age) { Name = name; Age = age; } public string Name { get; set; } public int Age { get; set; } }
解釋一下:小紅今年12,但她要工做,可能家庭困難吧。一、若是她有關係(有關係還家庭困難?解釋不了),找到BanZheng方法,給她身份證改爲「紅姐」18,拿去Main方法輸出驗證,果真輸出「紅姐」18。呵呵。但按我理解,ref若是是淺拷貝的話,Age做爲一個值類型屬性應該是從新烤了一份,其值不該該回傳給xiaohong啊,應該輸出「紅姐」12。看來有關係就是牛逼啊。二、若是她不要緊,找了個辦假證的BanJiaZheng,一驗證仍是「紅姐」18,若是按我理解,值傳遞是深拷貝的話,student參數應該和xiaohong是兩個徹底不一樣的對象,應該輸出「小紅」12,看來這個認證機構(個人理解)有水。因而我再查資料…
三、引用類型的值傳遞和引用傳遞揭祕
功夫不負有心人,找到這麼一篇好文http://www.cnblogs.com/duanwg/archive/2006/07/21/456247.html,其實看了它就能理解了,但我仍是根據上面的Demo作些改進,加深理解。
class Program { static void Main(string[] args) { Student xiaohong = new Student("小紅", 12); BanZheng(ref xiaohong); //BanJiaZheng(xiaohong); Console.WriteLine(xiaohong.Name + " " + xiaohong.Age); Console.ReadKey(); } static void BanZheng(ref Student student) { //student.Name = "紅姐"; //student.Age = 18; student = new Student("紅姐", 18); } static void BanJiaZheng(Student student) { //student.Name = "紅姐"; //student.Age = 18; student = new Student("紅姐", 18); } } class Student { public Student(string name, int age) { Name = name; Age = age; } public string Name { get; set; } public int Age { get; set; } }
這一次辦證方法改了,在方法體中student = new Student(…)。再到Main方法中驗證一下,若是調用BanZheng方法,輸出「紅姐」18,若是調用BanJiaZheng方法,輸出「小紅」12。看來有關係到何時都很牛逼啊。
畫兩個圖理解一下:
(1)若是是BanJiaZheng,即值傳遞的話:
變量xiaohong和student的棧中有相同的堆地址,都指向10000,即「小紅」12,而在BanJiaZheng方法中student = new Student(…),開闢了10010堆,student的棧中的堆地址改成10010,而xiaohong的棧中堆地址仍是10000。因此方法調用後xiaohong指向的對象沒變,依然是「小紅」12。
(2)若是是BanZheng,即引用傳遞的話:
變量xiaohong和student指向同一棧地址,在student = new Student(…)後,該棧001指向新的堆地址10010,而xiaohong也指向001棧。因此方法調用後xiaohong指向的對象變成了「紅姐」18。
至此,我總結出:值傳遞是傳遞棧中的值;引用傳遞是傳遞棧地址。
這一次我是蠻認真的寫的這篇博客,但願人氣能好一點,不吝留言賜教的話就感激涕零了。