16

次のようなものを持つことは可能ですか?

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

    public Bar Bars[int i]
    {
        ...
    }
}

そうでない場合、これを達成する方法はいくつかありますか? getFoo(int i) および getBar(int i) という関数を作成できることはわかっていますが、これをプロパティで行うことを望んでいました。

4

8 に答える 8

21

C# ではありません。

ただし、次のように、いつでもプロパティからコレクションを返すことができます。

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

public IList<Bar> Bars
{
    get { return ...; }
}

IList<T> にはインデクサーがあるため、次のように記述できます。

C whatever = new C();
Foo myFoo = whatever.Foos[13];

「return ...;」の行で IList<T> を実装するものは何でも返すことができますが、コレクションの読み取り専用ラッパーを返すものもあるかもしれません。AsReadOnly() メソッドを参照してください。

于 2009-01-10T17:10:03.940 に答える
18

これは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);  
        }
    }      
}
于 2009-10-30T21:15:58.803 に答える
6

方法があります.. 2 つの新しい型を定義して、コンパイラが 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;

  }

それを呼び出すには、次のように書く必要があります。

Employee Bob = MyEmployeeCollection[new EmployeeID(34)];

そして、暗黙の変換演算子を書いた場合:

public static implicit operator EmployeeID(int x)
{ return new EmployeeID(x); }

それを使用するためにそれを行う必要さえありません。次のように書くだけです。

Employee Bob = MyEmployeeCollection[34];

2 つのインデクサーが異なる型を返す場合でも、同じことが当てはまります...

于 2009-01-10T17:49:26.077 に答える
4

IndexPropertyクラスを試して、同じクラスで複数のインデクサーを有効にします

http://www.codeproject.com/Tips/319825/Multiple-Indexers-in-Csharp

于 2012-01-25T22:04:06.973 に答える
3

このようなことをしようとしている場合:

var myClass = new MyClass();

Console.WriteLine(myClass.Foos[0]);
Console.WriteLine(myClass.Bars[0]);

次に、FooクラスとBarクラス自体にインデクサーを定義する必要があります。つまり、すべてのFooオブジェクトをFoos内に配置し、Foosを直接インデックス付けをサポートするタイプインスタンスにします。

メンバープロパティに配列を使用する方法を示すには(既にインデクサーをサポートしているため)。

public class C {
    private string[] foos = new string[] { "foo1", "foo2", "foo3" };
    private string[] bars = new string[] { "bar1", "bar2", "bar3" };
    public string[] Foos { get { return foos; } }
    public string[] Bars { get { return bars; } }
}

あなたが言うことを可能にするでしょう:

 C myThing = new C();
 Console.WriteLine(myThing.Foos[1]);
 Console.WriteLine(myThing.Bars[2]);
于 2009-01-10T17:13:23.277 に答える
0

C#にはリターン型のオーバーロードはありません。入力パラメーターが異なる場合は、複数のインデクサーを定義できます。

于 2009-01-10T17:24:05.113 に答える
0

いいえ、できません。シグニチャを持つことができるメソッドのみが、戻りタイプによってのみ異なります。これは変換演算子です。インデクサーは、コンパイルするために異なる入力パラメータータイプを持っている必要があります。

于 2009-01-10T17:32:34.347 に答える