指向struct数组中的项的索引器不起作用

时间:2017-04-06 12:06:26

标签: c# arrays struct

我有一个名为Surface的类,在这个类中我有一个类型为struct Color的数组。

public class Surface
{
    private Color[,] pixels;

    public Color this[int x, int y]
    {
        get { return pixels[y, x]; }
    }
}

[StructLayout(LayoutKind.Explicit)]
public struct Color
{
    [FieldOffset(0)]
    public byte R;

    public void Set(byte r)
    {
        R = r;
    }
}

但是,当我尝试使用索引器访问颜色时,它不会更新。

mySurface[x, y].Set(255); // Will not work, i don't get an error but the color don't get updated.

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

  

我该如何解决这个问题?

你可以避免创建可变结构并暴露公共字段。这就是问题的根源所在。您的代码是有效的:

Color tmp = mySurface[x, y]; // Take a copy from the array...
tmp.Set(255); // This only affects the copy

要更改数组,您需要在索引器上调用setter。例如:

Color tmp = mySurface[x, y];
tmp.Set(255);
mySurface[x, y] = tmp;

假设你的struct实际上有几个值,如果你让你的struct不可变,但是提供返回新值的方法会更简单,就像DateTime.AddDays那样。然后你可以写代码如下: / p>

mySurface[x, y] = mySurface[x, y].WithRed(255);

选项,如果你真的想避免使用setter:

  • 使用C#7中的ref return:重新定义索引器以返回ref Color;虽然那时你不能有一个二传手。
  • 使Color成为一个类而不是结构
  • Color内使用引用类型,因此您无需更改Color值本身中的位。 (这真的很讨厌 - 我不是在暗示。)

答案 1 :(得分:0)

结构是值类型,因此如果通过调用pixels[y,x]从数组中获取它,您实际上将创建结构的副本以更改字段。

另见Unable to Modify struct Members