1

I want to assign some static values to my KeyValuePair object.

private IEnumerable<KeyValuePair<string, string>> getCountries()
{
    return new List<KeyValuePair<string, string>>() 
    { 
      { "code1", "value1" }, 
      { "code2", "value2" } 
    };
}

But this is throwing nooverloaded method error.

Mohammad Irshad
  • 139
  • 3
  • 11
  • Possible duplicate of [How to modify a KeyValuePair value?](https://stackoverflow.com/questions/13454721/how-to-modify-a-keyvaluepair-value) – Selim Yildiz Oct 01 '19 at 11:41
  • Possible duplicate of [How to initialize KeyValuePair object the proper way?](https://stackoverflow.com/questions/15495165/how-to-initialize-keyvaluepair-object-the-proper-way) – Kurubaran Oct 01 '19 at 11:42

3 Answers3

8
return new List<KeyValuePair<string, string>>()
{
    new KeyValuePair<string, string>("code1", "value1"),
    new KeyValuePair<string, string>("code2", "value2"),
};

If you're using .NET Core 2.0+, you can use the slightly less verbose:

return new List<KeyValuePair<string, string>>()
{
    KeyValuePair.Create("code1", "value1"),
    KeyValuePair.Create("code2", "value2"),
};

In C# 9, you can use target-typed new to write this as:

return new List<KeyValuePair<string, string>>()
{
    new("code1", "value1"),
    new("code2", "value2"),
};
canton7
  • 37,633
  • 3
  • 64
  • 77
1

Or with Dictionary you can achieve desired initialization style

var pairs = new Dictionary<string, string>
{
    { "one", "first" },
    { "two", "second" },
}.ToList();

pairs.Should().BeOfType<List<KeyValuePair<string, string>>>(); // Pass

Notice, that if later in the code you are going to just enumerate list of key value pairs, then you can use dictionary without explicitly converting it to the list.

var pairs = new Dictionary<string, string>
{
    { "one", "first" },
    { "two", "second" },
}

// later somewhere in the code

foreach(var pair in pairs)
{
    Console.WriteLine($"{pair.Key}: {pair.Value}")
}

If you are using values internally (inside class), you can use tuples.

private IEnumerable<(string Code, string Name)> GetCountries()
{
    yield return ("code", "Earth");
    yield return ("code", "Vulkan");
}

Which later can be consumed in more readable way

foreach(var country in GetCountries())
{
    Console.WriteLine($"{country.Code}: {country.Name}")
}

If type used across application, then instead of using key-value pairs you can show intentions of your code to the readers of your code and create custom type.

public class Country
{
    public string Code { get; }
    public string Name { get; }

    public Country(string code, string name)
    {
        Code = code;
        Name = name;
    }
}

private IEnumerable<Country> GetCountries()
{
    yield return new Country("code", "Earth");
    yield return new Country("code", "Vulkan");
}

Which later can be consumed in more readable way

foreach(var country in GetCountries())
{
    Console.WriteLine($"{country.Code}: {country.Name}")
}
Fabio
  • 31,528
  • 4
  • 33
  • 72
  • Note that you're not guaranteed to get the elements in the right order. With the current implementation of Dictionary you will, but this is not guaranteed to be the case in future. – canton7 Oct 01 '19 at 11:58
  • @canton7, does it guaranteed with current implementation of Dictionary? – Fabio Oct 01 '19 at 12:14
  • Nothing is guaranteed at all. It so happens that the current implementation of Dictionary will return items in insertion order *unless you remove/replace items*, but this is not in any way guaranteed at any point. – canton7 Oct 01 '19 at 12:15
  • @canton7, but List has such guaranty that values will be returned in same order even if you remove/add/replace items? – Fabio Oct 01 '19 at 12:17
  • Yes, a List has a specified order. A Dictionary does not. – canton7 Oct 01 '19 at 12:18
  • Good, I hope OP do not call `list.Sort()` before using it - in case order is important for his case – Fabio Oct 01 '19 at 12:21
0

You need to consider that both Key and Value properties of the generic class are read-only, so you cannot set them directly. Instead you need to take advantage of the class's constructor in order to set the desired pairs.



 public IEnumerable<KeyValuePair<string, string>> getCountries()
  {
        var keyValue1 = new KeyValuePair<string,string>("code1","value1");
        var keyvalue2 = new KeyValuePair<string,string>("code2","value2");

        var keyValueList = new List<KeyValuePair<string, string>> {keyValue1, keyvalue2};
        return keyValueList;

   }

Retro Code
  • 145
  • 1
  • 9