2

インデクサーはプロパティの拡張バージョンですか?.

4

3 に答える 3

2

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

class SampleCollection<T>
{
    // Declare an array to store the data elements.
    private T[] arr = new T[100];

    // Define the indexer, which will allow client code
    // to use [] notation on the class instance itself.
    // (See line 2 of code in Main below.)        
    public T this[int i]
    {
        get
        {
            // This indexer is very simple, and just returns or sets
            // the corresponding element from the internal array.
            return arr[i];
        }
        set
        {
            arr[i] = value;
        }
    }
}

// This class shows how client code uses the indexer.
class Program
{
    static void Main(string[] args)
    {
        // Declare an instance of the SampleCollection type.
        SampleCollection<string> stringCollection = new SampleCollection<string>();

        // Use [] notation on the type.
        stringCollection[0] = "Hello, World";
        System.Console.WriteLine(stringCollection[0]);
    }
}

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

于 2009-11-20T06:34:33.910 に答える
1

本当に視点次第です。

C#に関する限り、これらは2つの直交する概念です。クラスには0個以上のプロパティがあり、0個以上のインデクサーがある場合もあります。プロパティは名前で区別され、インデクサーは引数の型でオーバーロードされます(メソッドと同様)。それらは、gettor、settor、またはその両方を持つことができ、代入演算子(などの複雑な演算子を含む+=)がそれらの処理方法を知っているという点で似ています。

CLS(およびVB)の観点からは、インデクサーのようなものはありません。プロパティのみがあり、インデックスが付けられているものとされていないものがあります。インデックス付きプロパティは、値を読み取るためにレシーバー自体とは別に追加の値を提供し、値を書き込むためにレシーバーと新しい値を提供する必要があるプロパティです。追加の値はインデックスです。「デフォルトプロパティ」の概念もあります。デフォルトにできるのは、プロパティの1つのグループ(すべて同じ名前ですが、インデックスタイプが異なる)のみです。

CLRの観点からは、プロパティ自体は、タイプとそれに関連付けられた一連のメソッドを持つ単なる名前です。それ自体は実際には何の意味もありません。その名前のプロパティのアクセサーを探すときにメソッドがどこにあるかを示しているだけです。デフォルトのプロパティの概念はありません。

次に、これら3つのことを調整します...

CLSの規則により、プレーンプロパティは、CLRレベルで、対応するシグニチャ(1つはgetter用、もう1つはsetter用)を持つメソッドに関連付けられたプロパティによって表されます。Fooタイプのプロパティの場合、次のTようになります。

T get_Foo();
void set_Foo(T);

I1そして、タイプ、、I2...のインデックスを持つインデックス付きプロパティの場合:

T get_Foo(I1, I2, ...);
void set_Foo(I1, I2, ..., T);

デフォルトのプロパティを表すためDefaultMemberAttributeに、そのプロパティの名前を指定するために使用されます。

C#は、インデクサーをインデックス付きプロパティとして表すことにより、そのビューをCLSのビューと調整します。デフォルトでは、そのItemようなすべてのプロパティの名前が使用されますが、を使用IndexerNameAttributeして、プロパティに別の名前を付けるように強制することもできます。またDefaultMemberAttribute、そのプロパティのインデクサーを使用してクラスに固定されるため、VB(およびインデックス付きプロパティを表示する他のCLS準拠言語)ではデフォルトのプロパティと見なされます。

他の言語で記述されたクラスを使用する場合、C#はを検索しDefaultMemberAttributeます。存在する場合、それによって参照されるインデックス付きプロパティは、C#からそのクラスのインデクサーとして表示されます。get_Fooデフォルトではないインデックス付きプロパティには、アクセサメソッド(および)を直接呼び出すことによってのみC#からアクセスできますset_Foo。ただし、これは、COMでインポートされたインターフェイスのC#4で変更されます。

于 2009-11-20T06:56:18.730 に答える
0

インデクサーは、シンタックス シュガーの第 2 層です。プロパティを使用すると、get と set はメソッド呼び出しに変換され、これらのメソッドにはget_/のプレフィックスが付きset_ます。インデクサーの場合、インデクサーはメソッド Item() に変換されます。メソッドの最初の引数であるすべてのインデクサー引数を使用します。また、メソッドの前にget_/が付きます。set_

例を好む人のために:

string foo;
public string Foo {
    get {
        return foo;
    }
    set {
        foo = value;
    }
}
// becomes
string foo;
public string get_Foo() {
    return foo;
}
public void set_Foo(string value) {
    foo = value;
}

そして、ここでインデクサーで何が起こりますか:

string[] backingFoo;
public string this[int index] {
    get {
        return backingFoo[index];
    }
    set {
        backingFoo[index] = value;
    }
}
// becomes
string[] backingFoo;
public string get_Foo(int index) {
    return backingFoo[index];
}
public void set_Foo(int index, string value) {
    backingFoo[index] = value;
}
于 2009-11-20T06:46:33.057 に答える