无法修改存储在另一个属性中的结构的属性
本文关键字:属性 结构 另一个 修改 存储 | 更新日期: 2023-09-27 18:32:12
我有一个小问题,我无法修改存储在另一个属性中的结构的属性,我不知道为什么:
法典:
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;
它有效。谁能向我解释一下?
struct
是一种值类型,因此当您从属性访问它时,您获取的是struct
的副本,而不是基础字段 direclty。 因此,C# 不允许您修改该结构副本,因为它只是一个将被丢弃的临时对象。
因此,当您致电:
BNDTitleInfo.NavigovatNa = ...;
它首先调用属性上的get
并返回 bndTitleInfo
的副本,然后尝试设置 NavigovatNa
属性和副本。 C# 在这里给你错误,因为这不是你真正想做的事情,因此保护你免受自己的伤害。
但是,当您致电:
bndTitleInfo.NavigovatNa = ...;
您直接引用该字段,因此不会进行复制,也没有编译器问题。
长话短说,可变值类型不能成为好的属性(一般来说,你应该完全避免可变值类型)。
要纠正,你可以把它变成一个引用类型(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
编译器阻止了你遇到大问题。这是因为struct
的意思,即值类型语义,又名复制语义。
这里真正的答案是:不要把它变成struct
。即使不知道这些词是什么,我也99%确定这不应该是一个struct
。当然,我仍然有98.5%的把握认为它不应该是struct
,即使你只是说"我有一个叫InfoProTile
struct
"。
使BNDTileInfo
成为class
,除非你能非常清楚地解释为什么它是一个struct
,然后可以证明为什么它是一个可变struct
。