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

Sar*_*els 5 c# polymorphism inheritance dictionary 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) { }
}
Run Code Online (Sandbox Code Playgroud)

但是,尝试执行以下操作会出错:

var result = new SpecificRow
    {
        {MyEnum.Value, ""},
        {MyEnum.OtherValue, ""}
    };
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

集合初始化程序的最佳重载Add方法'Row.Add(string,string)'具有一些无效参数

我怎样才能使得在派生类上使用对象初始化器SpecificRow允许类型MyEnum?好像应该看到这个Add方法SpecificRow.

更新: 我实现了一个额外的接口,SpecificRow所以它现在看起来像这样:

public class SpecificRow : Row, IXmlSerializable,
    System.Collections.IEnumerable,
    ICollection<KeyValuePair<MyEnum, string>>
{ }
Run Code Online (Sandbox Code Playgroud)

但是,我仍然得到同样的Add错误.我将尝试IDictionary<MyEnum, string>下一步.

Rub*_*ben 7

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

new SpecificRow {
    { ? }
}
Run Code Online (Sandbox Code Playgroud)

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

所以支持你的语法

new SpecificRow {
    { MyEnum.Value, "" }
};
Run Code Online (Sandbox Code Playgroud)

你需要一个表格的重载

void Add(MyEnum key, string value)
Run Code Online (Sandbox Code Playgroud)

这里的所有都是它的.


Dan*_*fer 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. 变更的申报RowRow<T>,并实施IDictionary<T, string>,包括相关的接口.SpecificRow然后将实施Row<MyEnum>而不是仅仅Row.