一.知識點
二.問題
如果以上四個問題,你很自信,那麼以下,您就不要看了,因為我想說的東西真的很簡單。
如果你開始懷疑自己,可以繼續向下看。你自己到底真的理解嗎???
再看下面這段程式碼有沒有問題?
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Transform t = new Transform(); 6 t.v.x = 1; 7 t.ShowV(); 8 Console.Read(); 9 } 10 } 11 12 struct Vector 13 { 14 public float x; 15 public float y; 16 public float z; 17 } 18 19 class Transform 20 { 21 public Vector v { get; set; } 22 public void ShowV() 23 { 24 Console.WriteLine(v.x+"..."+v.y+"..."+v.z); 25 } 26 }
如果你覺得沒有問題,那麼你需要看看。這時候會編譯報錯,為啥,怎麼回事。
第6行編譯報錯:
三.分析
如果你非常清楚屬性的本質的話,那麼上述程式碼可以進行轉換,將屬性轉換為普通方法。(屬性的本質就是方法嘛)
class Program { static void Main(string[] args) { Transform t = new Transform(); t.GetVector().x = 1; t.ShowV(); Console.Read(); } } struct Vector { public float x; public float y; public float z; } class Transform { public Vector v; //set public void SetVector(Vector v) { this.v = v; } //get public Vector GetVector() { return v; } public void ShowV() { Console.WriteLine(v.x + "..." + v.y + "..." + v.z); } }
果然上述的改寫只是將屬性的寫法轉為本質寫法-寫成兩個普通的方法。結果還是報一樣的編譯錯誤。
,編譯報錯提示還是一樣的CS1612
再修改一下
Transform t = new Transform(); // t.GetVector().x = 10; 這邊編譯報錯 Vector v2 = t.GetVector(); v2.x = 10; t.ShowV(); Console.Read();
編譯列印結構是 0..0..0。
壓根就沒變,當然沒有變啊,因為v2是副本,你更改的只是副本,並沒有改變t中的v,同理,通過t.GetVector()也是一個副本,沒有意義。所以C#語法在對於這種情況,幫我們做了一個處理,如果寫了這樣的程式碼,直接給出編譯報錯。C#還是很智慧的。就是如果我們錯誤的進行一個無意義的操作,會直接給出提示。這裡給C#語法贊一個。
四.雜談
這一段程式碼雖然好像很簡單,但是真的藏的很深,樓主工作三年。記得曾經有一次去網易二面,被一個大佬問到這個問題,懵逼了,就亂猜吧,一開始說,那個列舉值中的x只是get,沒有set。然後大佬提示我不是的,然後我才誤打誤撞,恍然大悟,是因為列舉值傳遞是副本傳遞,再進行賦值操作沒有意義。現在想想,能出這個問題的大佬,真的很強,一道很簡單的問題,但是考察的東西真的很多很多。