试图创建不可变类 - 私有集被忽略

use*_*993 1 c# design-patterns immutability

我正在尝试创建一个表示矩阵的不​​可变类.但是,当行和列中的私有setter正在工作时,我仍然可以修改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!
Run Code Online (Sandbox Code Playgroud)

矩阵类:

   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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

nvo*_*igt 5

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

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;
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)