我有一个应该在该类中不可变的类,我只有给索引器一个私有集合属性,所以为什么这不是不可变的,我可以在数组中设置一些字段,就像在主类中看到的那样...

class ImmutableMatice
{
    public decimal[,] Array { get; private set; } // immutable Property

    public ImmutableMatice(decimal[,] array)
    {
        Array = array;
    }
    public decimal this[int index1, int index2]
    {
        get { return Array[index1, index2]; }
    }


........
在主方法中,如果我用数据填充此类并更改数据

    static void Main(string[] args)
    {
        decimal[,] testData = new[,] {{1m, 2m}, {3m, 4m}};
        ImmutableMatice matrix = new ImmutableMatice(testData);
        Console.WriteLine(matrix[0,0]); // writes 1
        testData[0, 0] = 999;
        Console.WriteLine(matrix[0,0]); // writes 999 but i thought it should
                                        // write 1 because class should be immutable?
    }
 }


有什么方法可以使此类不变吗?

是的,解决方案是将数组复制到构造函数中的新数组,如下所示:

    public ImmutableMatice(decimal[,] array)
    {
        decimal[,] _array = new decimal[array.GetLength(0),array.GetLength(1)];
        //var _array = new decimal[,] { };
        for (int i = 0; i < array.GetLength(0); i++)
        {
            for (int j = 0; j < array.GetLength(1); j++)
            {
                _array[i, j] = array[i, j];
            }
        }
        Array = _array;
    }

最佳答案

那是因为您实际上是在更改数组中的数据,而不是在索引器中。

static void Main(string[] args)
{
    decimal[,] testData = new[,] {{1m, 2m}, {3m, 4m}};
    ImmutableMatice matrix = new ImmutableMatice(testData);
    Console.WriteLine(matrix[0,0]); // writes 1
    testData[0, 0] = 999; // <--- THATS YOUR PROBLEM
    Console.WriteLine(matrix[0,0]); // writes 999 but i thought it should
                                    // write 1 because class should be immutable?
}


您可以将数组复制到构造函数中的private属性中,以避免这种情况。

请注意,您确实不能编写matrix[0,0] = 999;,因为索引器没有设置器。

编辑

就像克里斯指出的那样(我怎么会自己错过它?)-您根本不应该将数组公开为属性(这意味着在大多数情况下甚至不必是属性)。

请考虑以下代码:

private decimal[,] _myArray; // That's private stuff - can't go wrong there.

public decimal this[int index1, int index2]
{
    // If you only want to allow get data from the array, thats all you ever need
    get { return Array[index1, index2]; }
}

关于c# - C#:不可变的类别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25233256/

10-12 23:28