The .ToDictionary()
extension will throw an argument exception if we have duplicate keys added to the dictionary.
Ex:
List<int> listOfItems= new List<int>{1,1,2,3,4,4,5}; Dictionary<int, string> dict = listOfItems.ToDictionary(a => a, a => "item " + a); Console.WriteLine(dict.Count);
The above code throws the following exception
System.ArgumentException: An item with the same key has already been added.
In this post, we’ll create an extension method which will ignore duplicate keys from being added to a dictionary.
So, though we add duplicates into the list of items and have it to transform to a dictionary, our extension method should ignore the duplicates and returns a dictionary without duplicates.
First, let’s see what is in the original .ToDictionary()
extension method.
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) { if (source == null) throw Error.ArgumentNull("source"); if (keySelector == null) throw Error.ArgumentNull("keySelector"); if (elementSelector == null) throw Error.ArgumentNull("elementSelector"); Dictionary<TKey, TElement> d = new Dictionary<TKey, TElement>(comparer); foreach (TSource element in source) d.Add(keySelector(element), elementSelector(element)); return d; }
`.ToDictionary()` extension method is just a foreach over the enumerables. Each item in the list will be iterated and added to the dictionary. The accumulated dictionary is returned in the end.
To implement .ToSafeDictionary()
extension method, We’ll just extend the original .ToDictionary()
method to have contains check before adding any item to the dictionary. No magic, just a conditional check to ignore the key.
public static Dictionary<TKey, TElement> ToSafeDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) { if (source == null) throw new ArgumentException("source"); if (keySelector == null) throw new ArgumentException("keySelector"); if (elementSelector == null) throw new ArgumentException("elementSelector"); Dictionary<TKey, TElement> d = new Dictionary<TKey, TElement>(comparer); foreach (TSource element in source) { if (!d.ContainsKey(keySelector(element))) d.Add(keySelector(element), elementSelector(element)); } return d; }
Note that I’ve used the ArgumentException
when the values for the parameters is null instead of using the original source code Error.ArgumentNull
just to make sure we compile the code in C#.
Now if we run the same example code with .ToSafeDictionary
on the list of items then we should not get any exceptions.
Dictionary<int, string> dict = listOfItems.ToSafeDictionary(a => a, a => "item " + a, null); Console.WriteLine(dict.Count);
Karthik is a passionate Full Stack developer working primarily on .NET Core, microservices, distributed systems, VUE and JavaScript. He also loves NBA basketball so you might find some NBA examples in his posts and he owns this blog.
In this post, we’ll see how to test gRPC Server applications using different clients. And… Read More
In this post, we'll create a new gRPC project in ASP.NET Core and see what's… Read More
In this blog post, we’ll see how to run dotnet core projects without opening visual… Read More
Programmatically evaluating policies is useful when we want to provide access or hide some data… Read More
We saw how we could set up policy-based authorization in our previous article. In this… Read More
What is policy-based authorization and how to set up policy-based authorization with handlers and policies… Read More
This website uses cookies.