2016-03-04 95 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

现在我明白了,谢谢! –