C#实现类,其行为类似于2dim数组

时间:2017-12-10 00:33:53

标签: c#

是否可以创建自定义集合,其初始化语法如2dim数组,例如:

var matrix = new Matrix(){{1,1},{2,2}};

修改

我理解它似乎像一个非常常见的问题,但索引器不是问题,问题是初始化语法。这是我的一时兴起。那么,是否有可能得到完全相同的表达式?我得到的最简单的是:

var matrix = new Matrix() { new List<int>() {1, 2} };

5 个答案:

答案 0 :(得分:4)

要实现初始化语法,您可以在对象上使用集合初始值设定项,但如果该对象实现IEnumerable,则

如果对象实现IEnumerable,则可以添加在初始化对象时将调用的Add方法。这里举例说明如何在一个简单的矩阵类中初始化条目:

public class Matrix : IEnumerable
{
    public int[,] _data = new int[3,3];

    public void Add(int x, int y, int value)
    {
        _data[x,y] = value;
    }
    public IEnumerator GetEnumerator()
    {
        throw new NotImplementedException();
    }    
}

我可以像这样初始化它:

var myObject = new Matrix() {
    {1,2,3}, 
    {0,0,10}
};

这相当于写作:

var myObject = new Matrix();
myObject.Add(1,2,3);
myObject.Add(0,0,10);

Custom Collection Initializers是一个关于自定义集合初始化程序的问题,除其他外,它引用了关于它们的规范。

如前所述,这仅适用于实现IEnumerable的对象。如上所示,您不必使用{em>有用的实现IEnumerable来实现此功能,但我不鼓励您制作IEnumerable内容以获取此行为该对象实际上不是IEnumerable

答案 1 :(得分:2)

public int this[int index1, int index2] { 
    // This is the get accessor. 
    get { 
        return index1 + index2;
    }
}

来源:http://www.java2s.com/Tutorial/CSharp/0140__Class/Atwodimensionalindexer.htm

答案 2 :(得分:1)

如果您希望它使用数组初始化语法,只需添加protected: /// Safety check used only from at(). void _M_range_check(size_type __n) const { if (__n >= this->size()) __throw_out_of_range_fmt(__N("vector::_M_range_check: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); } 方法并实施Add

IEnumerable

答案 3 :(得分:0)

你可以效仿它,比如说。内部清单:

为了安全起见(ish),您需要添加大量支票, 通过您可以提供的初始化列表使其工作 和IEnumerable构造函数并将其传递给它。

AFAIK没有办法实现“自动解构”的愿望 矩阵是真的。

    // main method - declares a matrix, fills one value, prints all
    static void Main()
    {
        Mat m = new Mat(8, 8);
        m[4, 2] = 55;

        Console.WriteLine(m);
        Console.ReadLine();
    }

    private class Mat
    {
        public Mat(int mRow, int mCol)
        {
            maxCol = mCol;
            maxRow = mRow;
            // prefill data with 0 - could use default
            data = new List<int>(Enumerable.Range(0, mCol * mRow).Select(n => 0)); 
        }

        // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/
        public int this[int row, int col]
        {
            get
            {
                return data[row * maxCol + col];
            }
            set { data[row * maxCol + col] = value; }
        }

        // lenghty to string method 
        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.Append("[ ");
            for (int r = 0; r < maxRow; r++)
            {
                sb.Append("[ ");

                for (int c = 0; c < maxCol; c++)
                {
                    sb.Append(this[r, c]);
                    if (c < maxCol - 1)
                        sb.Append(", ");
                }
                sb.Append(" ]\n");
                if (r < maxRow - 1)
                    sb.Append(", ");
            }
            sb.Append(" ]\n");
            return sb.ToString();
        }

        private int maxCol;
        private int maxRow;
        private List<int> data { get; set; }
    }

答案 4 :(得分:0)

class Matrix : IEnumerable
{
    List<int[]> rowList = new List<int[]>();

    public void Add(params int[] row)
    {
        rowList.Add(row);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return rowList.GetEnumerator();
    }
}