folks,
I’ve get compilation error(‘Can not modify the return value of dictionary because it’s not a variable’) in next code :
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;
}
}
But if i’ll replace struct(Cell) with class, then it works fine.
Why it happens ?
This won’t work as you expect. When you call:
grids[grid].A copy of the struct is returned from the indexer, not a reference. So when you set into it:
grids[grid].RowIndex = grid.CurrentCell.RowIndex;You are actually setting into a copy of the struct. This copy is then immediately discarded. All of this behaviour stems from the value type semantics of structs.
All you can do if you use a struct is set a brand new struct into the cell:
grids[grid] = new Cell { RowIndex = 3, ColumnIndex = 1 };Or pull a copy of the old one and set it back in (ignoring for a moment that structs should really always be made immutable 🙂 :
Changing the definition to a class means the indexer returns a reference to that class, which you can mutate as both your reference and the dictionary’s reference are pointing at the same underlying object.
The compiler is saying (in not so many words) that you are inadvertently trying to change a copy of what you think you are changing.
You can make the same mistake easily if you expose a struct as a property of a class and try to mutate struct members thus:myClass.MyPointStruct.X = 2;(This appears to give the same error message in the new compiler at least, I could have sworn at one point it used to let you do this…)
Or if you cast the struct to an interface, boxing boxes a copy.
This question is very similar:
Modify Struct variable in a Dictionary