C# object initializer wanting to use wrong Add method
I have the following class hierarchy:
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) { }
}
However, trying to do the following gives an error:
var result = new SpecificRow
{
{MyEnum.Value, ""},
{MyEnum.OtherValue, ""}
};
I get this error:
The best overloaded Add method 'Row.Add(string, string)' for the collection initializer has some invalid arguments
How can I make it so that using an object initializer on the derived class SpecificRow allows type MyEnum? It seems like it should see the Add method in SpecificRow.
Update: I implemented an extra interface on SpecificRow so it now looks like this:
public class SpecificRow : Row, IXmlSerializable,
Syste开发者_JS百科m.Collections.IEnumerable,
ICollection<KeyValuePair<MyEnum, string>>
{ }
However, I still get the same Add error. I'm going to try implementing IDictionary<MyEnum, string> next.
A collection initializer does not necessarily look at any ICollection.Add(x) method. More specifically, for a collection initializer
new SpecificRow {
{ ? }
}
C# looks at any Add method with signature Add(?); if ? contains comma's, C# looks at an Add method with multiple arguments. The compiler does not have any special handling of KeyValuePair<,> at all. The reason { string, string } works, is because your base class has an overload Add(string, string), and not because it has an overload for Add(KeyValuePair<string, string>).
So to support your syntax for
new SpecificRow {
{ MyEnum.Value, "" }
};
you need an overload of the form
void Add(MyEnum key, string value)
That's all there is to it.
It looks like it's because you're only implementing IDictionary<string, string>, and all the other interfaces associated with it. Your Add(KeyValuePair<MyEnum, string>) method isn't implementing any interface member, it's just another member of the SpecificRow class, which happens to be named Add, which is why it is getting ignored.
You should be able to do one of the following, depending on what your requirements are:
- Implement
IDictionary<MyEnum, string>in addition toIDictionary<MyEnum, string>, including the dependent interfaces (ICollection<KeyValuePair<MyEnum, string>>, etc). - Implement
IDictionary<MyEnum, string>instead ofIDictionary<MyEnum, string>, again including the dependent interfaces. - Change the declaration of
RowtoRow<T>, and implementIDictionary<T, string>, including the dependent interfaces.SpecificRowwould then implementRow<MyEnum>instead of justRow.
Ruben's answer is definitely the best, but if you didn't want to add Add(MyEnum key, string value) then you could also initialize the collection like so:
var result = new SpecificRow
{
new KeyValuePair<MyEnum, string>(MyEnum.Value, ""}),
new KeyValuePair<MyEnum, string>(MyEnum.OtherValue, ""})
};
加载中,请稍侯......
精彩评论