C # инициализатор объекта хочет использовать неправильный метод Add - PullRequest
5 голосов
/ 01 февраля 2010

У меня есть следующая иерархия классов:

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> далее.

Ответы [ 3 ]

7 голосов
/ 02 февраля 2010

Инициализатор коллекции не обязательно просматривает какой-либо метод 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)

Это все, что нужно сделать.

5 голосов
/ 01 февраля 2010

Похоже, это потому, что вы реализуете только IDictionary<string, string> и все другие интерфейсы, связанные с ним.Ваш Add(KeyValuePair<MyEnum, string>) метод не реализует ни одного члена интерфейса, это просто еще один член класса SpecificRow, которому случается с именем Add, поэтому его игнорируют.

В зависимости от ваших требований вы сможете выполнить одно из следующих действий:

  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>, включаязависимые интерфейсы.SpecificRow будет реализовывать Row<MyEnum> вместо Row.
1 голос
/ 02 февраля 2010

Ответ Рубена, безусловно, лучший, но если вы не хотите добавлять Add(MyEnum key, string value), вы можете также инициализировать коллекцию следующим образом:

var result = new SpecificRow
{
    new KeyValuePair<MyEnum, string>(MyEnum.Value, ""}),
    new KeyValuePair<MyEnum, string>(MyEnum.OtherValue, ""})
};
...