2016-03-04 101 views
2

考慮流動的代碼片段C#匿名值類型性質

static void Main() 
    { 
     var x = new MyStruct 
     { 
      Item = new StringWrapper("abc") 
     }; 

     Console.WriteLine(x.Item.PublicField); 
     x.Item.SetValue("xyz"); 
     Console.WriteLine(x.Item.PublicField); 

     var y = new 
     { 
      Item = new StringWrapper("abc") 
     }; 

     Console.WriteLine(y.Item.PublicField); 
     y.Item.SetValue("xyz"); 
     Console.WriteLine(y.Item.PublicField); 
    } 

    public struct MyStruct 
    { 
     public StringWrapper Item; 
    } 

    public struct StringWrapper 
    { 
     public string PublicField; 

     public StringWrapper(string v) 
     { 
      PublicField = v; 
     } 

     public void SetValue(string v) 
     { 
      PublicField = v; 
     } 
    } 

和輸出:
ABC
XYZ
ABC
ABC

MYSTRUCT可以聲明爲類,輸出將保持不變。 {abc,abc}輸出的一部分對我來說是一個驚喜,因爲我期望匿名類型被轉換爲類或結構,並且行爲相同。

我覺得我錯過了一些明顯的東西,並會很感激任何幫助。

謝謝。

+0

http://stackoverflow.com/questions/18292087/accessing-and-changing-structs-as -property-vs-as-field,你可以通過搜索找到更多解釋 - https://www.bing.com/search?q=c%23+struct+field+vs+property –

+0

'class StringWrapper'將解決它。不得不提的是,匿名類型的屬性只讀 –

回答

5

這裏的區別在於你的MyStruct(結構體或類)公開了一個公共字段,而匿名類(new { })公開了屬性。

當您從字段或變量訪問值類型時,您不會獲得副本,而是直接訪問該實例。因此對它進行更改將它們存儲在實例中。

當您通過屬性或方法訪問它時,會得到您的StringWrapper的返回副本,並且更改該副本並不會更改存儲在匿名類專用字段中的內容。

只是爲了展示,你可以通過你的Item領域的財產也得到了相同的行爲:

public StringWrapper Item { get; set; } 
+0

現在我明白了,謝謝! –