Question

I have a method that returns an ILookup. In some cases I want to return an empty ILookup as an early exit. What is the best way of constructing an empty ILookup?

Was it helpful?

Solution

Further to the answers from mquander and Vasile Bujac, you could create a nice, straightforward singleton-esque EmptyLookup<K,E> class as follows. (In my opinion, there doesn't seem much benefit to creating a full ILookup<K,E> implementation as per Vasile's answer.)

var empty = EmptyLookup<int, string>.Instance;

// ...

public static class EmptyLookup<TKey, TElement>
{
    private static readonly ILookup<TKey, TElement> _instance
        = Enumerable.Empty<TElement>().ToLookup(x => default(TKey));

    public static ILookup<TKey, TElement> Instance
    {
        get { return _instance; }
    }
}

OTHER TIPS

There's no built-in, so I'd just write an extension method that runs something along the lines of new T[0].ToLookup<K, T>(x => default(K));

I strongly doubt returning null would be more correct here. It's almost never the case that you want to return null from a method which returns a collection (as opposed to an empty collection.) I could not possibly disagree more with people who are suggesting that.

You can create a singleton class for empty lookups.

using System.Linq;

public sealed class EmptyLookup<T, K> : ILookup<T, K> 
{
        public static readonly EmptyLookup<T, K> Instance { get; }
            = new EmptyLookup<T, K>();

        private EmptyLookup() { }

        public bool Contains(T key) => false;

        public int Count => 0;

        public IEnumerable<K> this[T key] => Enumerable.Empty<K>();

        public IEnumerator<IGrouping<T, K>> GetEnumerator()
          => Enumerable.Empty<IGrouping<K, V>>().GetEnumerator();

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
 }

then you can write code like this:

var x = EmptyLookup<int, int>.Instance;

The benefit of creating a new class is that you can use the "is" operator and check for type equality:

if (x is EmptyLookup<,>) {
 // ....
}

Based on LukeH answer, I'd create a static class Lookup with an Empty<TKey, TElement> method. In this way you could use is just the same way as Enumerable.Empty<T>.

public static class Lookup
{
    public static ILookup<TKey, TElement> Empty<TKey, TElement>()
        => Enumerable.Empty<TElement>().ToLookup(x => default(TKey));
}

Example Usage: Lookup.Empty<string, string>()

Create an empty list, then execute ToLookup() on it, like this:

List<Point> items = new List<Point>();
ILookup<int, int> lookup = items.ToLookup(p => p.X, p => p.Y);

Good luck!

Or something more in the spirit of LINQ:

    public static class Utility
{

    public static ILookup<TKey, TElement> EmptyLookup<TKey, TElement>(Func<TKey, TKey> keySelector,
                                                                      Func<TKey, TElement> elementSelector)
    {
        return Enumerable.Empty<TKey>().ToLookup(keySelector, elementSelector);
    }

}

You can return null

or Exception

But you should note it in class comment

Added:+ This is more obvious than some extension method

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top