13

いくつかのコードを読んで、私が前に見たことがないこのスニペットに出くわしました:

public SomeClass {
  public someInterface this[String strParameter] {
    get {
      return SomeInternalMethod(strParameter);
    }
  }
}

次のように呼ばれているようです。

SomeClass _someClass = new SomeClass();
SomeInterface returnedValue = _someClass["someString"];

この関数がどこに適切であるか、またはこのスタイルで書く意図が何であるかに興味があります。たとえば、単に関数を呼び出すよりもこれが好まれるのはなぜですか?

4

11 に答える 11

23

言語仕様のセクション10.9を参照してください。

インデクサーは、オブジェクトを配列と同じ方法でインデックス付けできるようにするメンバーです。

インデクサーとプロパティは概念が非常に似ていますが、次の点で異なります。

  • プロパティはその名前で識別されますが、インデクサーはその署名で識別されます。
  • プロパティは単純な名前(§7.5.2)またはメンバーアクセス(§7.5.4)を介してアクセスされますが、インデクサー要素は要素アクセス(§7.5.6.2)を介してアクセスされます。
  • プロパティは静的メンバーにすることができますが、インデクサーは常にインスタンスメンバーです。
  • プロパティのgetアクセサーは、パラメーターのないメソッドに対応しますが、インデクサーのgetアクセサーは、インデクサーと同じ仮パラメーターリストを持つメソッドに対応します。
  • プロパティのセットアクセサーは、valueという名前の単一のパラメーターを持つメソッドに対応しますが、インデクサーのsetアクセサーは、インデクサーと同じ仮パラメーターリストにvalueという名前の追加パラメーターを持つメソッドに対応します。
  • インデクサーアクセサーがインデクサーパラメーターと同じ名前のローカル変数を宣言するのは、コンパイル時のエラーです。
  • オーバーライドするプロパティ宣言では、継承されたプロパティは構文base.Pを使用してアクセスされます。ここで、Pはプロパティ名です。オーバーライドするインデクサー宣言では、継承されたインデクサーは構文base [E]を使用してアクセスされます。ここで、Eはコンマで区切られた式のリストです。
于 2010-01-06T22:35:49.360 に答える
20

多くの回答は、インデクサーを使用する理由ではなく、インデクサーとは何かに焦点を当てているようです。

私に関する限り、インデクサーを使用する動機は次のとおりです。

ある種のコレクションを持つクラスで作業していますが、そのクラスをユーザー (クラスの消費者) にコレクションであるかのように見せたいとします。

私が思いつく最も良い例はDataRow、ADO.NET のクラスです。の 5 番目のセルの値を取得する場合は、またはDataRowを使用できます。後者の形式は便利で論理的なショートカットであり、インデクサーを使用する理由がよくわかります。ユーザーにとって、 は単なるセルの集合と考えることができます (実際にはそれ以上ですが)。そのため、実際に取得していることを覚えておく必要なく、セル値を直接取得および設定できることは理にかなっています。 / を設定します。DataRow.Item[4]DataRow[4]DataRowItem

それが役立つことを願っています。

于 2010-01-06T23:10:32.910 に答える
6

多くの場合、「インデックス」構文は非常に理にかなっています。SomeClassが何らかのコレクションを表す場合に特に役立ちます。

于 2010-01-06T22:34:15.753 に答える
3

質問で述べたように、連想配列ルックアップ(別名「辞書スタイル」)を実行できます。

そしてそれが要点です。そのような人、特にPythonやPHPのようなそれが組み込まれている言語から来ている人

于 2010-01-06T22:34:44.817 に答える
3

「this」キーワードはインデクサーです

http://msdn.microsoft.com/en-us/library/6x16t2tx.aspxから

「インデクサーを使用すると、クラスまたは構造体のインスタンスに配列と同じようにインデックスを付けることができます。インデクサーは、アクセサーがパラメーターを受け取ることを除いて、プロパティに似ています。」

于 2010-01-06T22:35:29.137 に答える
1

以前に似たようなものに出くわしたことがあるかもしれません:

var myList = new List<string>();
myList.Add("One");
myList.Add("Two");
myList.Add("Three");

for(int i = 0; i < myList.Count; i++) {
    string s = myList[i];
}

インデクサーは、コレクションを実装するオブジェクトの "主キー" です。これは、必要に応じて、.GetValue(index) のような関数を簡単に記述するための簡単な方法です。しかし、それはまた意図を明確にします。

于 2010-01-06T22:37:19.670 に答える
0

これは、インデックス演算子の実装です[ ]

于 2010-01-06T22:34:54.213 に答える
0

これは演算子のオーバーロードです。たとえば、collection[someIndex]などの配列表記を使用してアクセスすることが理にかなっているコレクションクラスを作成している場合に便利です。

もちろん、collection.GetElement(someIndex)関数と同等のものを書くこともできますが、それはスタイル/読みやすさの問題です。

于 2010-01-06T22:34:59.457 に答える
0

このメソッドは、キーと値のペアのクラスで使用できます。

類似のクラスがc#にあるかどうかはわかりませんが、c ++ STLには、でメソッドを呼び出すマップクラスがあり、SomeObject["key"]そのキーに関連付けられた「値」を返します。

于 2010-01-06T22:35:31.200 に答える
0

これはインデクサーと呼ばれ、配列構文を使用してList <>、ArrayList、Dictionary<>およびその他すべてのコレクションを使用できます。

これは単なる構文糖衣ですが、正しく使用すると読みやすさが向上します。

于 2010-01-06T22:35:42.417 に答える
0

私の意見では、これは単なる構文上の便宜です。使用しない場所:

public SomeClass {
  private int[] nums;
  public GetVal this[int ind] {
    get {
      return nums[ind]; // this is pointless since array is already indexed
    }
  }
}

どのようなメリットがありますか:

public Matrix {
  private Dictionary<string, double> matrixData; // Matrix indecies, value
  public double this[int row, int col] {
    get {
      return matrixData[string.Format("{0},{1}", row, col)];
    }
  }
}

ご覧のとおり、何らかの理由で、データは文字列キーでインデックス付けされたディクショナリであり、これを 2 つの整数インデックスで呼び出したいのですが、データ型を変更したくありません。

Matrix m = new Matrix();
...
Console.WriteLine( m[1,2] );
于 2015-01-25T19:45:28.220 に答える