我正在尝试创建一个不可变的类来表示一个矩阵。但是,尽管“行和列”中的私有设置器正在运行,但我仍然能够修改Elements的内容。如何正确创建不可变的类?

    var matrix = new Matrix(new double[,] {
                                          {1,1,1,1},
                                          {1,2,3,4},
                                          {4,3,2,1},
                                          {10,4,12, 6}});

    matrix.Elements[1,1] = 30; // This still works!


矩阵类:

   class Matrix
    {
        public uint Rows { get; private set; }
        public uint Columns { get; private set; }
        public double[,] Elements { get; private set; }

        public Matrix(double[,] elements)
        {
            this.Elements = elements;
            this.Columns = (uint)elements.GetLength(1);
            this.Rows = (uint)elements.GetLength(0);
        }
    }

最佳答案

数组不是一成不变的。您需要使用索引器来具有不可变的类型:

class Matrix
{
    public uint Rows { get; private set; }
    public uint Columns { get; private set; }
    private readonly double[,] elements;

    public Matrix(double[,] elements)
    {
        // this will leave you open to mutations of the array from whoever passed it to you
        this.elements = elements;

        // this would be perfectly immutable, for the price of an additional block of memory:
        // this.elements = (double[,])elements.Clone();

        this.Columns = (uint)elements.GetLength(1);
        this.Rows = (uint)elements.GetLength(0);
    }

    public double this[int x, int y]
    {
      get
      {
        return elements[x, y];
      }

      private set
      {
        elements[x, y] = value;
      }
    }
}


您可以通过在实例上使用索引器来使用它:

var matrix = new Matrix(new double[,] {
                                      {1,1,1,1},
                                      {1,2,3,4},
                                      {4,3,2,1},
                                      {10,4,12, 6}});

double d = matrix[1,1]; // This works, public getter

matrix[1,1] = d; // This does not compile, private setter

10-07 13:13