一尘不染

修改字典中的Struct变量

c#

我有一个这样的结构:

public struct MapTile
{
    public int bgAnimation;
    public int bgFrame;
}

但是当我用foreach遍历它来更改动画帧时,我做不到…

这是代码:

foreach (KeyValuePair<string, MapTile> tile in tilesData)
{
        if (tilesData[tile.Key].bgFrame >= tilesData[tile.Key].bgAnimation)
        {
            tilesData[tile.Key].bgFrame = 0;
        }
        else
        {
            tilesData[tile.Key].bgFrame++;
        }
}

它给了我编译错误:

Error 1 Cannot modify the return value of 'System.Collections.Generic.Dictionary<string,Warudo.MapTile>.this[string]' because it is not a variable
Error 2 Cannot modify the return value of 'System.Collections.Generic.Dictionary<string,Warudo.MapTile>.this[string]' because it is not a variable

为什么不能在字典中的结构内更改值?


阅读 270

收藏
2020-05-19

共1个答案

一尘不染

索引器将返回该值的 副本
。对该副本进行更改不会对字典中的值产生任何影响……编译器阻止您编写错误的代码。如果要修改字典中的值,则需要使用类似以下内容的方法:

// Note: copying the contents to start with as you can't modify a collection
// while iterating over it
foreach (KeyValuePair<string, MapTile> pair in tilesData.ToList())
{
    MapTile tile = pair.Value;
    tile.bgFrame = tile.bgFrame >= tile.bgAnimation ? 0 : tile.bgFrame + 1;
    tilesData[pair.Key] = tile;
}

请注意,这 避免了无缘无故地进行多次查找(原始代码正在这样做)。

就个人而言,我强烈建议 不要 从一个可变的结构开始,请注意…

当然,另一种选择是使其成为引用类型,此时您可以使用:

// If MapTile is a reference type...
// No need to copy anything this time; we're not changing the value in the
// dictionary, which is just a reference. Also, we don't care about the
// key this time.
foreach (MapTile tile in tilesData.Values)
{
    tile.bgFrame = tile.bgFrame >= tile.bgAnimation ? 0 : tile.bgFrame + 1;
}
2020-05-19