C#

.ToSafeDictionary() extension method in csharp

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.

Original ToDictionary extension method source code

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.

ToSafeDictionary extension method

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);

References

Disqus Comments Loading...
Share
Published by
Karthik Chintala

Recent Posts

2 Good Tools To Test gRPC Server Applications

In this post, we’ll see how to test gRPC Server applications using different clients. And… Read More

2 years ago

Exploring gRPC project in ASP.NET Core

In this post, we'll create a new gRPC project in ASP.NET Core and see what's… Read More

2 years ago

Run dotnet core projects without opening visual studio

In this blog post, we’ll see how to run dotnet core projects without opening visual… Read More

2 years ago

Programmatically evaluating policies in ASP.NET Core

Programmatically evaluating policies is useful when we want to provide access or hide some data… Read More

2 years ago

Multiple authorization handlers for the same requirement in ASP.NET Core

We saw how we could set up policy-based authorization in our previous article. In this… Read More

2 years ago

Policy-Based Authorization in ASP.NET Core

What is policy-based authorization and how to set up policy-based authorization with handlers and policies… Read More

2 years ago

This website uses cookies.