无法修改存储在另一个属性中的结构的属性

本文关键字:属性 结构 另一个 修改 存储 | 更新日期: 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