Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 向字典中的结构赋值时出现编译错误_C#_Winforms_Class_Struct - Fatal编程技术网

C# 向字典中的结构赋值时出现编译错误

C# 向字典中的结构赋值时出现编译错误,c#,winforms,class,struct,C#,Winforms,Class,Struct,各位, 我在下一个代码中遇到编译错误(“无法修改dictionary的返回值,因为它不是变量”): public class BaseForm : Form { protected void StoreGridViewPosition(DataGridView grid) { if (grids.ContainsKey(grid)) { grids[grid].RowIndex = grid.CurrentCell.Ro

各位, 我在下一个代码中遇到编译错误(“无法修改dictionary的返回值,因为它不是变量”):

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;
    }
}
公共类基表单:表单
{
受保护的void StoreGridViewPosition(DataGridView网格)
{
if(网格。容器(网格))
{
grids[grid].RowIndex=grid.CurrentCell.RowIndex;
grids[grid].ColumnIndex=grid.CurrentCell.ColumnIndex;
}
单元s=新单元();
s、 行指数=213;
}
受保护的无效LoadGridViewPosition(DataGridView网格)
{
}
私有字典网格=新字典();
专用结构单元
{
公共综合指数;
公共指数;
}
}
但如果我用类替换结构(单元),那么它就可以正常工作。
为什么会发生这种情况?

这不会像您预期的那样起作用。当你打电话时:

网格[网格]。

从索引器返回结构的副本,而不是引用。因此,当你开始时:

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

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

如果使用结构,则可以在单元格中设置一个全新的结构:

grids[grid]=新单元格{RowIndex=3,ColumnIndex=1}

或者拉一个旧结构的副本并将其放回(暂时忽略结构确实应该始终保持不可变的:-):

将定义更改为类意味着索引器返回对该类的引用,当引用和字典的引用都指向同一基础对象时,可以对该类进行变异

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

myClass.MyPointStruct.X=2

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

或者,如果将结构强制转换为接口,则装箱一个副本

这个问题非常相似:


这不会像您预期的那样起作用。当你打电话时:

网格[网格]。

从索引器返回结构的副本,而不是引用。因此,当你开始时:

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

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

如果使用结构,则可以在单元格中设置一个全新的结构:

grids[grid]=新单元格{RowIndex=3,ColumnIndex=1}

或者拉一个旧结构的副本并将其放回(暂时忽略结构确实应该始终保持不可变的:-):

将定义更改为类意味着索引器返回对该类的引用,当引用和字典的引用都指向同一基础对象时,可以对该类进行变异

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

myClass.MyPointStruct.X=2

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

或者,如果将结构强制转换为接口,则装箱一个副本

这个问题非常相似:


构造一个值类型,因此当你从字典中得到一个值时,你得到的是字典中的值的副本。C#实际上是在阻止你有坏习惯
惊喜…

构造一个值类型,这样当你从字典中得到的是字典中的值的副本。C#实际上是在阻止你有坏习惯
惊喜…

当你的StoreGridViewPosition调用你的单元格时,你会得到里面结构的副本。您的呼叫会更新该值,然后将其丢弃(即没有任何有用的内容)

当你的StoreGridViewPosition调用你的单元格时,你会得到里面结构的副本。您的呼叫会更新该值,然后将其丢弃(即没有任何有用的内容)

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