C#多个索引器

sma*_*007 14 c# indexer properties

是否有可能具有以下内容:

class C
{
    public Foo Foos[int i]
    {
        ...
    }

    public Bar Bars[int i]
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果没有,那么我可以通过哪些方式实现这一目标?我知道我可以创建名为getFoo(int i)和getBar(int i)的函数,但我希望用属性来做这个.

小智 17

不是在C#中,没有.

但是,您始终可以从属性返回集合,如下所示:

public IList<Foo> Foos
{
    get { return ...; }
}

public IList<Bar> Bars
{
    get { return ...; }
}
Run Code Online (Sandbox Code Playgroud)

IList <T>有一个索引器,因此您可以编写以下内容:

C whatever = new C();
Foo myFoo = whatever.Foos[13];
Run Code Online (Sandbox Code Playgroud)

在线上"返回...;" 你可以返回任何实现IList <T>的东西,但是你可以在集合周围返回一个只读包装器,参见AsReadOnly()方法.


小智 16

这来自C#3.0规范

"重载索引器允许类,结构或接口声明多个索引器,前提是它们的签名在该类,结构或接口中是唯一的."

public class MultiIndexer : List<string>  
{
    public string this[int i]
    {
        get{
            return this[i];
        }
    }
    public string this[string pValue]
    {
        get
        {
            //Just to demonstrate
            return this.Find(x => x == pValue);  
        }
    }      
}
Run Code Online (Sandbox Code Playgroud)


Cha*_*ana 5

有一种方法..如果您定义2个新类型以使编译器能够区分两个不同的签名...

  public struct EmployeeId
  { 
      public int val;
      public EmployeeId(int employeeId) { val = employeeId; }
  }
  public struct HRId
  { 
      public int val;
      public HRId(int hrId) { val = hrId; }
  }
  public class Employee 
  {
      public int EmployeeId;
      public int HrId;
      // other stuff
  }
  public class Employees: Collection<Employee>
  {
      public Employee this[EmployeeId employeeId]
      {
          get
             {
                foreach (Employee emp in this)
                   if (emp.EmployeeId == employeeId.val)
                      return emp;
                return null;
             }
      }
      public Employee this[HRId hrId]
      {
          get
             {
                foreach (Employee emp in this)
                   if (emp.HRId == hrId.val)
                      return emp;
                return null;
             }
      }
      // (or using new C#6+ "expression-body" syntax)
      public Employee this[EmployeeId empId] => 
             this.FirstorDefault(e=>e.EmployeeId == empId .val;
      public Employee this[HRId hrId] => 
             this.FirstorDefault(e=>e.EmployeeId == hrId.val;

  }
Run Code Online (Sandbox Code Playgroud)

然后调用它,您将必须编写:

Employee Bob = MyEmployeeCollection[new EmployeeID(34)];
Run Code Online (Sandbox Code Playgroud)

如果您编写了一个隐式转换运算符:

public static implicit operator EmployeeID(int x)
{ return new EmployeeID(x); }
Run Code Online (Sandbox Code Playgroud)

那么您甚至不必这样做就可以使用它,您可以编写:

Employee Bob = MyEmployeeCollection[34];
Run Code Online (Sandbox Code Playgroud)

即使两个索引器返回不同的类型,情况也一样。

  • 我想任何你没有立即认出并且不熟悉的东西,都有一点“魔法”的感觉,不是吗?当我第一次看到 lambdas 时,我完全被搞糊涂了。 (2认同)