【问题标题】:Compilation error when assign value to struct in dictionary为字典中的结构赋值时出现编译错误
【发布时间】:2011-09-16 11:53:52
【问题描述】:

各位, 我在下一个代码中出现编译错误('无法修改字典的返回值,因为它不是变量'):

public class BaseForm : Form
{

    protected void StoreGridViewPosition(DataGridView grid)
    {

        if (grids.ContainsKey(grid))
        {
            grids[grid].RowIndex = grid.CurrentCell.RowIndex;
            grids[grid].ColumnIndex = grid.CurrentCell.ColumnIndex;
        }

        Cell s = new Cell();
        s.RowIndex = 213;
    }

    protected void LoadGridViewPosition(DataGridView grid)
    {
    }

    private Dictionary<DataGridView, Cell> grids = new Dictionary<DataGridView, Cell>();

    private struct Cell
    {
        public int RowIndex;
        public int ColumnIndex;
    }
}

但是,如果我将 struct(Cell) 替换为 class,那么它可以正常工作。 为什么会这样?

【问题讨论】:

    标签: c# winforms class struct


    【解决方案1】:

    这不会像您期望的那样工作。当你打电话时:

    grids[grid].

    结构的副本从索引器返回,而不是引用。所以当你进入它时:

    grids[grid].RowIndex = grid.CurrentCell.RowIndex;

    您实际上是在设置结构的副本。然后立即丢弃该副本。所有这些行为都源于结构的值类型语义。

    如果你使用结构,你所能做的就是在单元格中设置一个全新的结构:

    grids[grid] = new Cell { RowIndex = 3, ColumnIndex = 1 };

    或者提取旧的副本并将其放回原处(暂时忽略结构确实应该始终设为不可变 :-) :

    var cell = grids[grid];
    cell.RowIndex = 3;
    grids[grid] = cell;
    

    将定义更改为一个类意味着索引器返回一个对该类的引用,您可以对其进行变异,因为您的引用和字典的引用都指向同一个底层对象。

    编译器在说(用不多的话)您无意中尝试更改您认为正在更改的内容的副本。 如果您将结构公开为类的属性并尝试改变结构成员,您很容易犯同样的错误:

    myClass.MyPointStruct.X = 2;

    (这似乎至少在新编译器中给出了相同的错误消息,我可以发誓它曾经让你这样做......)

    或者,如果您将结构转换为接口,则将副本装箱。

    这个问题很相似:

    Modify Struct variable in a Dictionary

    【讨论】:

      【解决方案2】:

      当您的 StoreGridViewPosition 调用您的 Cell 时,您会获得内部结构的副本。您的调用会更新该值,然后将其丢弃(即没有任何用处)。

      【讨论】:

        【解决方案3】:

        构造一个值类型,因此当来自您的字典时,您得到的是字典中那个值的副本。 C# 实际上是在防止你犯错 惊喜……

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-04-25
          • 2016-07-06
          • 1970-01-01
          • 2019-11-26
          • 1970-01-01
          • 1970-01-01
          • 2014-11-23
          • 1970-01-01
          相关资源
          最近更新 更多