Dictionary extends the base class to add keys and values to the dictionary

  • 2020-05-24 06:00:14
  • OfStack

Add keys and values to the dictionary
Adding keys and values is done using the Add method, but many times we are afraid to add them because of Dictionary < TKey, TValue > Repetition is not allowed. The Add method raises ArgumentException when trying to add duplicate keys.
Most of the time, we write something like this:

var dict = new Dictionary<int, string>();
// ...
//  situation 1 : does not exist before adding 
if (dict.ContainsKey(2) == false) dict.Add(2, "Banana");
//  situation 2 : does not exist to add, exists to replace 
if (dict.ContainsKey(3) == false) dict.Add(3, "Orange");
else dict[3] = "Orange";

Actually, the second case can be written as follows

dict[3] = "Orange";

But a lot of friends will have doubts about this approach, not sure if it will go wrong.
No matter which way you write it, the biggest feeling you get when you use a dictionary is the fear that something will go wrong, so the code will be verbose.
I do this every time I use a dictionary. I get tired of it after a long time. I simply expand 1 and use the following two ways to deal with the above two situations:

/// <summary>
///  Try adding keys and values to the dictionary: if they don't exist, add them; Exists, neither adds nor casts 
/// </summary>
public static Dictionary<TKey, TValue> TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
    if (dict.ContainsKey(key) == false) dict.Add(key, value);
    return dict;
/// <summary>
///  Add or replace keys and values to the dictionary: if none exist, add; Exists, replaces 
/// </summary>
public static Dictionary<TKey, TValue> AddOrReplace<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
    dict[key] = value;
    return dict;

The two methods, TryAdd and AddOrReplace, are self-describing and easy to use:

dict.TryAdd(2, "Banana");
dict.AddOrReplace(3, "Orange");

Or put them together like Linq or jQuery 1:

dict.TryAdd(1, "A")
    .TryAdd(2, "B")
    .AddOrReplace(3, "C")
    .AddOrReplace(4, "D")
    .TryAdd(5, "E");

Let's look at another question:

Get the value

Getting a value from a dictionary is usually done in the following manner:

string v = "defaultValue";
//  way 1
if (dict.ContainsKey(3)) v = dict[3];
//  way 2
bool isSuccess = dict.TryGetValue(3, out v);

Use the index method to get the first 1 must first judgment, otherwise the KeyNotFoundException exception will be thrown when it does not exist.
I particularly hate the second approach because out requires a variable to be declared in advance and at least two lines of code.
Take a look at the GetValue extension:

/// <summary>
///  Gets the value associated with the specified key, or returns the default value of the input if none exists 
/// </summary>
public static TValue GetValue<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue defaultValue = default(TValue))
    return dict.ContainsKey(key) ? dict[key] : defaultValue;

Easy to use:

var v1 = dict.GetValue(2);         // Returns if it does not exist  null
var v2 = dict.GetValue(2, "abc");  // Nonexistent return   " abc " 

One line of code will do it.

Batch add

List < T > Class has an AddRange method that adds another collection directly to the current collection without the foreach loop:

List<string> roles = new List<string>();
roles.AddRange(new[] { "role2", "role2" });

Pretty convenient, poor Dictionary < TKey, TValue > Class, fortunately there are extension methods:

/// <summary>
///  Batch adds key-value pairs to the dictionary 
/// </summary>
/// <param name="replaceExisted"> If existing, whether to replace </param>
public static Dictionary<TKey, TValue> AddRange<TKey, TValue>(this Dictionary<TKey, TValue> dict, IEnumerable<KeyValuePair<TKey, TValue>> values, bool replaceExisted)
    foreach (var item in values)
        if (dict.ContainsKey(item.Key) == false || replaceExisted)
            dict[item.Key] = item.Value;
    return dict;

Use examples:

dict[3] = "Orange";

Related articles: