Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,
    System.Collections.IEnumerable,
    ICollection<KeyValuePair<MyEnum, string>>
{ }

However, I still get the same Add error. I'm going to try implementing IDictionary<MyEnum, string> next.

like image 463
Sarah Vessels Avatar asked Feb 01 '10 20:02

Sarah Vessels


1 Answers

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.

like image 53
Ruben Avatar answered Sep 28 '22 04:09

Ruben