【问题标题】:Having multiple Indexer with the same signature拥有多个具有相同签名的索引器
【发布时间】:2016-03-14 17:24:34
【问题描述】:

是否可以有两个或多个索引器(或类似的东西)具有相同的签名?

所以它看起来像这样

    private int[,] X;
    public int this[int a]
    {
        set
        {
            X[a, 0] = value;
        }

    }
    public int this[int a]
    {
        set
        {
            X[a, 1] = value;
        }
    }

这会产生错误,因为这两种方法都是无名的并且具有相同的签名。那么是否可以命名这些方法但保留设置值的能力。即

C.FirstCol(2) = 3; //Same as C.X[2,0] = 3
C.SecondCol(5) = 4; //Same as C.X[5,1] = 4

编辑:我会尝试更好地解释它:

C.SetX(value) 行可以使用属性更改为C.X = value

C.Set(num, value) 行可以使用索引器更改为C[num] = value

我要问的是如何更改这些行

C.SetA(num, value)
C.SetB(num, value)

C.A[num] = value
C.B[num] = value

或者

C.A(num) = value
C.B(num) = value

没有 A 或 B 作为数组

【问题讨论】:

  • 如果他们有相同的签名,编译器怎么知道你想调用哪一个?
  • 不,我认为你甚至不能拥有 byte 和 int,因为存在隐式转换

标签: c# .net methods indexer


【解决方案1】:

您可以使用二维索引器(如果我正确理解您的问题!):

private int[,] X;
public int this[int row, int column]
{
    set
    {
        X[row, column] = value;
    }

}

像这样使用:

C[2, 0] = 3;
C[5, 1] = 4;

【讨论】:

    【解决方案2】:

    这是不可能的 - 编译器如何知道您要使用哪个索引器?并且没有您希望在示例中包含的语法。

    你可以这样介绍方法:

    public void FirstCol(int rowIndex, int value)
    {
        X[rowIndex, 0] = value;
    }
    

    和第二列的类似内容,等等。但老实说,我看不出重点。也许引入二维索引器会更好?

    【讨论】:

    • 要知道要使用哪个索引器 - 这就是为什么我问是否可以将方法(带有名称)用作set,例如C.FirstRow(2) = 3;。而且我知道在这个例子中使用两个参数索引器会更好,但这只是一个例子来展示我在寻找什么
    【解决方案3】:

    此答案旨在说明,但不一定实用。如果你这样定义一个类:

    class Indexer<TKey, TValue>
    {
        Func<TKey, TValue> getter;
        Action<TKey, TValue> setter;
        public Indexer(Func<TKey, TValue> getter, Action<TKey, TValue> setter)
        {
            this.getter = getter;
            this.setter = setter;
        }
        public TValue this[TKey key]
        {
            get { return getter(key); }
            set { setter(key, value); }
        }
    }
    

    你可以这样使用它:

    Indexer<int, int> firstColumn = new Indexer<int, int>(
        i => X[i, 0],
        (i, v) => X[i, 0] = v);
    public Indexer<int, int> FirstColumn
    {
        get { return firstColumn; }
    }
    
    Indexer<int, int> secondColumn = new Indexer<int, int>(
        i => X[i, 1],
        (i, v) => X[i, 1] = v);
    public Indexer<int, int> SecondColumn
    {
        get { return secondColumn; }
    }
    

    这会让你这样做:

    C.FirstColumn[2] = 3;
    C.SecondColumn[4] = 5;
    

    但是,我不建议这样做!简单地使用方法Set(int i, int j, int value) 或索引器int this[int i, int j] 会更直接。

    【讨论】:

      【解决方案4】:

      你可以创建一个索引包装器:

      class Indexer
      {
        private int[,] data;
        private int index;
      
        public Indexer(int index, int[,] data)
        {
          this.index = index;
          this.data = data;
        }
      
        public int this[int a]
        {
          set {data[a,index] = value;}
        }
      }
      

      然后在你的代码中使用它:

      class Foo
      {
        private int[,] data;
        private readonly Indexer first;
        private readonly Indexer second;
      
        public Foo()
        {
          first = new Indexer(0, data);
          second = new Indexer(1, data);
        }
      
        public Indexer First
        {
          get{ return first;}
        }
      
        public Indexer Second
        {
          get{ return second;}
        }
      }
      

      现在你可以说:

      Foo f = new Foo();
      f.First[2] = 3;
      f.Second[5] = 4;
      

      【讨论】:

        猜你喜欢
        • 2017-09-08
        • 2011-09-25
        • 2011-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-10
        • 2016-03-01
        • 1970-01-01
        相关资源
        最近更新 更多