我有一点问题,我无法修改存储在另一个属性中的结构属性,我不明白为什么:
码:
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;
}
Run Code Online (Sandbox Code Playgroud)
错误:
Error: Error 3 Cannot modify the return value of '...ViewModel.TilesModel.BNDTileInfo' because it is not a variable
Run Code Online (Sandbox Code Playgroud)
我不懂,因为如果我把它改成:
bndTileInfo.NavigovatNa = NavigovatNa.MainPage;
Run Code Online (Sandbox Code Playgroud)
有用.有人可以向我解释一下吗?
A struct是一个值类型,因此当您从属性访问它时,您将获得一个struct而不是底层字段direclty 的副本.因此,C#将不允许您修改结构的副本,因为它只是一个将被丢弃的临时对象.
所以,当你打电话:
BNDTitleInfo.NavigovatNa = ...;
Run Code Online (Sandbox Code Playgroud)
它首先调用get属性并返回一个副本bndTitleInfo,然后尝试设置NavigovatNa属性和副本.C#在这里给出了错误,因为这不是你真正想做的事情,因此可以保护你自己.
但是,当你打电话:
bndTitleInfo.NavigovatNa = ...;
Run Code Online (Sandbox Code Playgroud)
您正在直接引用该字段,因此不会进行任何复制,也不存在编译器问题.
它的长短是由于可变值类型不能产生好的属性(通常你应该完全避免使用可变值类型).
要纠正,你可以使它成为引用类型(class)或者你可以使你的struct不可变,这意味着你必须分配一个全新的结构实例来改变它的值.
如果你看一下MSDN的建议,通常struct最适合小的,逻辑单值,不可变的结构:在类和结构之间选择
因为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
Run Code Online (Sandbox Code Playgroud)
编译器已经阻止你遇到大问题.这是因为什么struct 意思,即值类型语义,即复制语义.
这里真正的答案是:不要那样做struct.即使不知道这些词是什么,我99%肯定不应该是一个struct.当然,struct即使你只是说"我有一个struct叫InfoProTile" ,我仍然有98.5%肯定它不应该是一个.
做BNDTileInfo一个class,除非你能非常清楚地解释为什么它是一个struct,然后可以证明为什么它是一个可变的 struct.