【问题标题】:C# implement class which behaves like 2dim arrayC# 实现类,其行为类似于 2dim 数组
【发布时间】:2017-12-10 00:33:52
【问题描述】:

是否可以创建自定义集合,具有像 2dim 数组这样的初始化语法,例如:

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

编辑

我知道这似乎是一个非常常见的问题,但索引器不是问题,问题在于初始化语法。这是我的小奇思妙想。那么,是否有可能得到完全相同的表达方式?我得到的最相似的是:

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

【问题讨论】:

  • 是的,可以创建一个类.. 对以下内容进行谷歌搜索,您会看到大量示例。C# Stackoverflow alternative to 2 dimensional array 可能是List of List,例如List&lt;List&lt;int&gt;&gt;
  • 这个矩阵应该能够做到二维数组不能做到的事情吗?
  • 它应该看起来像数组,但可以做更多的事情。没关系,我编辑问题并描述我的问题

标签: c#


【解决方案1】:

要实现初始化语法,您可以在对象上使用集合初始化器,但如果该对象实现了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 的对象。如上所示,您不必拥有IEnumerable有用 实现,但如果对象不是真的,我会劝阻您不要使用IEnumerable 来获得此行为一个IEnumerable

【讨论】:

    【解决方案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

    【讨论】:

    • 我不知道谁赞成这个。您只是返回索引的总和 - 这不是索引器的用途。它是关于访问内部数据结构和(可能)将使用的索引类型从 2dim 更改为 1dim 或其他......
    • @PatrickArtner:它显示了二维索引器的语法。实际的正文不是很有用,但回答者大概认为如何编写索引器是提问者的问题,而不是那个索引器的内容。
    • 索引器不是问题)我只想达到某种初始化语法(以及适用于数组的所有其他语法)
    【解决方案3】:

    如果您希望它使用数组初始化语法,只需添加一个Add 方法并实现IEnumerable

     public void Add(int a, int b) { ... }
    

    【讨论】:

    • 您还需要该对象来实现IEnumerable(请参阅我的答案)。
    【解决方案4】:

    你可以模仿它,f.e.带有内部列表:

    为了确保安全(ish),您需要添加大量检查, 通过您可以提供的 Initializerlist 使其工作 和 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; }
        }
    

    【讨论】:

      【解决方案5】:
      class Matrix : IEnumerable
      {
          List<int[]> rowList = new List<int[]>();
      
          public void Add(params int[] row)
          {
              rowList.Add(row);
          }
      
          IEnumerator IEnumerable.GetEnumerator()
          {
              return rowList.GetEnumerator();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        • 2010-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多