想要使用错误的Add方法的C#对象初始值设定项

时间:2010-02-01 20:47:40

标签: c# inheritance dictionary polymorphism object-initializers

我有以下类层次结构:

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 个答案:

答案 0 :(得分:7)

集合初始值设定项不一定会查看任何ICollection.Add(x)方法。更具体地说,对于集合初始化程序

new SpecificRow {
    { ? }
}

C#查看带有签名Add(?)的任何Add方法;如果?包含逗号,C#查看带有多个参数的Add方法。编译器对KeyValuePair&lt;,&gt;没有任何特殊处理。一点都不{ string, string }有效的原因是因为您的基类有一个重载Add(string, string),而不是,因为它有Add(KeyValuePair<string, string>)的重载。

所以支持

的语法
new SpecificRow {
    { MyEnum.Value, "" }
};

您需要表单重载

void Add(MyEnum key, string value)

这就是它的全部。

答案 1 :(得分:5)

看起来好像是因为你只实现了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

答案 2 :(得分:1)

Ruben的答案肯定是最好的,但是如果你不想添加Add(MyEnum key, string value)那么你也可以像这样初始化集合:

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