Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a an easier way to initialize a List<KeyValuePair<T, U>>, like a Dictionary<T, U>?

Tags:

c#

.net

Actually I need something like List<KeyValuePair<T, U>> but I want to be able to initialize it like dictionary (i.e. without writing new KeyValuePair every time). Like this:

Dictionary<string, string> dic = new Dictionary<string, string>
{
    { "key1", "value1"}, 
    { "key2", "value2"}
};
like image 487
Poma Avatar asked Sep 12 '11 12:09

Poma


2 Answers

EDIT: It turns out .NET does have a combination list/dictionary type already: OrderedDictionary. Unfortunately this is a non-generic type, making it rather less attractive in my view. However, it retains the insertion order if you just call Add repeatedly.

It's a little strange as calling Add does not affect entries where a key already exists, whereas using the indexer to add a key/value pair will overwrite a previous association. Basically it doesn't seem like a terribly nice API, and I would personally still avoid it unless your use case exactly matches its behaviour.


No, .NET doesn't have any insertion-order-preserving dictionaries. You could always write your own list-based type with the relevant Add method. This might even be one of the few places I'd consider extending an existing type:

public class KeyValueList<TKey, TValue> : List<KeyValuePair<TKey, TValue>>
{
    public void Add(TKey key, TValue value)
    {
        Add(new KeyValuePair<TKey, TValue>(key, value));
    }
}

Then:

var list = new KeyValueList<string, string>
{
    { "key1", "value1"}, 
    { "key2", "value2"}
};

An alternative is to use composition, but my gut feeling is that this is a reasonable use of inheritance. I can't place why I'm happy in this case but not usually, mind you...

like image 161
Jon Skeet Avatar answered Sep 23 '22 08:09

Jon Skeet


Because you do not have a dictionary you cannot use a dictionary initiailzer. You have a list so you could use a list initializer which will be the closest you could get:

var l = new List<KeyValuePair<string, string>> 
{
    new KeyValuePair<string, string>("key1", "value1"),
    new KeyValuePair<string, string>("key2", "value2"),
};

Here's the minimum requirement for you to use dictionary initializer: the class must implement IEnumerable and the class must have a public method Add which takes 2 arguments (where the first argument represents the key and the second argument the value). So you could write a custom class which satisfies those requirements and you will be able to use the syntax you have shown in your question.

like image 20
Darin Dimitrov Avatar answered Sep 23 '22 08:09

Darin Dimitrov