5

Dictionaryから継承するカスタムDictionaryクラスを作成しました。ただし、クラスの使用方法によっては、インデクサーを呼び出すときに奇妙なことが起こります。クラスの簡略化されたバージョンは次のとおりです。

public class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
    public new TValue this[TKey key]
    {
        get
        {
            return base[key];
        }
        set
        {
            base[key] = value;
        }
    }
}

次に、インスタンスを作成して何かを追加します。以下は正常に機能します。つまり、インデクサーのセッターにブレークポイントを設定すると、ヒットします。

MyDictionary<int, string> dict = new MyDictionary<int, string>();
dict[0] = "some value";

ただし、このようにすると(IDictionary変数にインスタンス化されます):

IDictionary<int, string> dict = new MyDictionary<int, string>();
dict[0] = "some value";

インデクサーのセッターのブレークポイントにヒットしなくなります。つまり、他の何かを呼び出している必要があります。.NETのディクショナリ実装(クラスが継承するもの)を見ると、オーバーライドするインデクサー以外のインデクサーは見つかりません。また、他のインデクサーからは継承されません。だから問題は、何が起こっているのかということです。

4

1 に答える 1

12

ポイントは、newインデクサー宣言のキーワードにあります。これは基本クラスのインデクサーをオーバーライドせず、基本クラスまたはインターフェイス(例のように)からインデクサーにアクセスするたびに、基本クラスIDictionaryのインデクサーが呼び出されます。virtualさらに、基本クラスインデクサーはDictionary<TKey, TValue>クラス定義でマークされていないため、オーバーライドできません。

メソッド宣言の新しい修飾子に関するこの記事を検討してください

ここでは、継承の代わりに構成を使用してみてください。

確かな場合は、次の例を使用して IDictionary<TKey, TValue、より抽象的なインターフェイスではなく、正確にカスタム動作が必要であることを確認してください。ICollection<KeyValuePair<TKey, TValue>>IEnumerable<KeyValuePair<TKey, TValue>>

public class MyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    IDictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();

    //LOTS of other methods here, that are required by IDictionary<TKey, TValue>
    //their implementation would be delegation to dictionary instance

    public TValue this[TKey key] //implementation of a interface
    {
        get
        {
            return dictionary[key];
        }
        set
        {
            dictionary[key] = value;
        }
    }
}
于 2013-03-22T13:30:43.550 に答える