2012-04-24 71 views
3

我有一个小问题,我不能修改存储在另一个属性结构的财产,我不知道为什么:不能修改存储在一个结构的属性另一个属性

代码:

public struct InfoProTile 
    { 
     public string Nazev { get; set; } 
     public double Hodnota { get; set; } 
     public TypValue TypValue { get; set; } 
     public NavigovatNa NavigovatNa { get; set; } 
    } 

     public InfoProTile BNDTileInfo { get { return bndTileInfo; } set { bndTileInfo = value; } } private InfoProTile bndTileInfo; 

     LoadModel() 
    { 
     ... 
     BNDTileInfo = new InfoProTile(); 
     BNDTileInfo.NavigovatNa = NavigovatNa.MainPage; 
    } 

错误:

Error: Error 3 Cannot modify the return value of '...ViewModel.TilesModel.BNDTileInfo' because it is not a variable 

我不明白这一点,因为如果我只是把它变成:

bndTileInfo.NavigovatNa = NavigovatNa.MainPage; 

它的工作原理。任何人都可以请给我解释一下吗?

+3

C#职业生涯的下一步是了解值类型和引用类型之间的区别:) – MattDavey 2012-04-24 21:31:05

回答

7

A struct是一个值类型,因此当您从属性中访问它时,您将收回struct的副本,而不是基础字段direclty。因此,C#不会允许您修改该结构的副本,因为这只是一个将被丢弃的临时对象。

所以,当你拨打:

BNDTitleInfo.NavigovatNa = ...; 

它首先要求对房地产get并返回bndTitleInfo一个副本,然后尝试设置NavigovatNa属性和复制。 C#在这里给你提供了错误,因为这不是你真正想做的事情,因此保护了你自己。

但是,当你拨打:

bndTitleInfo.NavigovatNa = ...; 

您直接引用领域,因此没有仿造而成,没有编译器的问题。

长和短的是,可变值类型不会做出好的属性(并且一般来说,您应该完全避免可变值类型)。

要纠正,您可以使其成为参考类型(class),或者您可以使您的struct不可变,这意味着您必须分配一个全新的结构实例来更改其值。

如果你看一下MSDN的建议,在一般struct是最适合向小型化,逻辑单值的,一成不变的结构:Choosing Between Classes and Structures

7

因为BNDTileInfo是一个属性,你得到的数据的克隆。当它被丢弃时,对克隆的更改将丢失,即您的代码为:

var tmp = BNDTileInfo; // tmp is a completely separate clone 
tmp.NavigovatNa = NavigovatNa.MainPage; // change the local clone 
// discard the clone - our change was wasted 

编译器已停止您收到大问题。这是因为什么struct意味着,即价值型语义,即复制语义。

这里真正的答案是:不要那样做struct。即使不知道这些词是什么,我99%肯定不应该是struct。当然,即使你刚才说“我有一个structInfoProTile”,我仍然是98.5%肯定它不应该是struct

BNDTileInfo一个class,除非你能解释一下很清楚为什么它是一个struct然后可以证明为什么它是一个可变struct

相关问题