5

次のクラス階層があります。

public class Row : ICloneable, IComparable, IEquatable<Row>,
    IStringIndexable, IDictionary<string, string>,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    System.Collections.IEnumerable
{ }

public class SpecificRow : Row, IXmlSerializable,
    System.Collections.IEnumerable
{
    public void Add(KeyValuePair<MyEnum, string> item) { }
}

ただし、次のことを実行しようとするとエラーが発生します。

var result = new SpecificRow
    {
        {MyEnum.Value, ""},
        {MyEnum.OtherValue, ""}
    };

このエラーが発生します:

コレクション初期化子に最適なオーバーロードされたAddメソッド'Row.Add(string、string)'には、いくつかの無効な引数があります

SpecificRow派生クラスでオブジェクト初期化子を使用して型を許可するようにするにはどうすればよいMyEnumですか?Addのメソッドが表示されるはずSpecificRowです。

更新: 追加のインターフェースを実装したSpecificRowので、次のようになります。

public class SpecificRow : Row, IXmlSerializable,
    System.Collections.IEnumerable,
    ICollection<KeyValuePair<MyEnum, string>>
{ }

ただし、それでも同じAddエラーが発生します。次に実装してみますIDictionary<MyEnum, string>

4

3 に答える 3

7

コレクション初期化子は、必ずしもICollection.Add(x)メソッドを参照する必要はありません。より具体的には、コレクション初期化子の場合

new SpecificRow {
    { ? }
}

C#は、署名Add(?)を使用してAddメソッドを調べます。もしも ?カンマが含まれている場合、C#は複数の引数を持つAddメソッドを調べます。コンパイラには、KeyValuePair <、>の特別な処理はまったくありません。理由{ string, string }は、基本クラスにオーバーロードがあるためであり、のオーバーロードがあるためではAdd(string, string)ありませんAdd(KeyValuePair<string, string>)

したがって、の構文をサポートするには

new SpecificRow {
    { MyEnum.Value, "" }
};

フォームのオーバーロードが必要です

void Add(MyEnum key, string value)

これですべてです。

于 2010-02-01T21:19:25.090 に答える
5

を実装しているだけIDictionary<string, string>で、それに関連する他のすべてのインターフェースがあるためのようです。あなたのメソッドはインターフェースメンバーを実装していません。それはクラスAdd(KeyValuePair<MyEnum, string>)の別のメンバーであり、たまたま名前が付けられているため、無視されています。SpecificRowAdd

要件に応じて、次のいずれかを実行できるはずです。

  1. IDictionary<MyEnum, string>に加えてIDictionary<MyEnum, string>、依存インターフェース(ICollection<KeyValuePair<MyEnum, string>>など)を含めて実装します。
  2. IDictionary<MyEnum, string>の代わりに実装IDictionary<MyEnum, string>します。これも依存インターフェイスを含みます。
  3. の宣言をに変更しRow、依存インターフェイスを含めてRow<T>を実装します。次に、の代わりに実装します。IDictionary<T, string>SpecificRowRow<MyEnum>Row
于 2010-02-01T20:57:00.530 に答える
1

ルーベンの答えは間違いなく最高ですが、追加したくない場合は、Add(MyEnum key, string value)次のようにコレクションを初期化することもできます。

var result = new SpecificRow
{
    new KeyValuePair<MyEnum, string>(MyEnum.Value, ""}),
    new KeyValuePair<MyEnum, string>(MyEnum.OtherValue, ""})
};
于 2010-02-01T22:23:11.493 に答える