Dzm*_*try 1 c# struct class winforms
大家好,我在下一段代码中得到了编译错误('不能修改字典的返回值,因为它不是变量'):
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;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我用类替换struct(Cell),那么它可以正常工作.为什么会这样?
这不会像你期望的那样工作.你打电话的时候:
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;
Run Code Online (Sandbox Code Playgroud)
将定义更改为类意味着索引器返回对该类的引用,您可以在引用和字典引用指向同一基础对象时进行变异.
编译器说(不是很多的话)你无意中试图改变你认为你正在改变的副本. 如果将struct作为类的属性公开并尝试改变struct成员,则可以轻松地犯同样的错误:
myClass.MyPointStruct.X = 2;
(这似乎至少在新的编译器中给出了相同的错误信息,我可以在某一时刻宣誓它曾经让你这样做......)
或者,如果将结构转换为接口,则装箱副本.
这个问题非常相似: