Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an empty IReadOnlyCollection

I'm creating an extension method for MultiValueDictionary to encapsulate frequent ContainsKey checks and I was wondering what was the best way to create an empty IReadOnlyCollection?.

What I've used so far is new List<TValue>(0).AsReadOnly() but there must be a better way, an equivilant to IEnumerable's Enumerable.Empty

public static IReadOnlyCollection<TValue> GetValuesOrEmpty<TKey, TValue>(this MultiValueDictionary<TKey, TValue> multiValueDictionary, TKey key)
{            
    IReadOnlyCollection<TValue> values;
    return !multiValueDictionary.TryGetValue(key, out values) ? new List<TValue>(0).AsReadOnly() : values;
}
like image 473
i3arnon Avatar asked Aug 10 '14 09:08

i3arnon


People also ask

What is IReadOnlyCollection?

The IReadOnlyCollection interface extends the IEnumerable interface and represents a basic read-only collection interface. It also includes a Count property apart from the IEnumerable members as shown in the code snippet given below.

How do you initialize IReadOnlyList?

Try this: List<string> listData = new List<string>(); public IReadOnlyList<string> readOnlyData = listData. AsReadOnly();


1 Answers

EDIT: The new .Net 4.6 adds an API to get an empty array: Array.Empty<T> and arrays implement IReadOnlyCollection<T>. This also reduces allocations as it only creates an instance once:

IReadOnlyCollection<int> emptyReadOnlyCollection = Array.Empty<int>();

What I ended up doing is mimicking the implementation of Enumerable.Empty using new TElement[0]:

public static class ReadOnlyCollection
{
    public static IReadOnlyCollection<TResult> Empty<TResult>()
    {
        return EmptyReadOnlyCollection<TResult>.Instance;
    }

    private static class EmptyReadOnlyCollection<TElement>
    {
        static volatile TElement[] _instance;

        public static IReadOnlyCollection<TElement> Instance
        {
            get { return _instance ?? (_instance = new TElement[0]); }
        }
    }
}

Usage:

IReadOnlyCollection<int> emptyReadOnlyCollection = ReadOnlyCollection.Empty<int>();
like image 177
i3arnon Avatar answered Oct 15 '22 10:10

i3arnon