如何创建一个空的IReadOnlyCollection

时间:2014-08-10 09:46:59

标签: c# .net readonly-collection multi-value-dictionary

我正在为MultiValueDictionary创建一个扩展方法来封装频繁的ContainsKey检查,我想知道创建空IReadOnlyCollection的最佳方法是什么?

我到目前为止使用的是new List<TValue>(0).AsReadOnly(),但必须有更好的方法,与IEnumerable的{​​{1}}

等效
Enumerable.Empty

5 个答案:

答案 0 :(得分:16)

编辑:新的.Net 4.6添加了一个API来获取一个空数组:Array.Empty<T>和数组实现IReadOnlyCollection<T>。这也减少了分配,因为它只创建一次实例:

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

我最终做的是使用new TElement[0]模仿Enumerable.Empty的实施:

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

用法:

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

答案 1 :(得分:3)

我认为Enumerable.Empty之类的内容只适用于只读集合,但是:

  • List<T>已经实现了IReadOnlyCollection<T>,因此您可以通过不调用AsReadOnly()并简单地转换列表来避免一个对象分配。这不太安全&#34;在理论上但在实践中几乎不重要。

  • 或者,您可以缓存返回的ReadOnlyCollection以避免任何对象分配(缓存对象除外)。

答案 2 :(得分:3)

据我所知,没有内置方式(有兴趣知道是否有)。也就是说,您可以使用以下内容:

IReadOnlyCollection<TValue> readonlyCollection = new ReadOnlyCollection<TValue>(new TValue[] { });

您可以选择将结果缓存为ReadOnlyCollection空数组,无论您拥有多少实例,它都将始终相同。

答案 3 :(得分:2)

如何使用与Enumerable.Empty类似的语法:

/// <summary>
/// Contains a method used to provide an empty, read-only collection.
/// </summary>
public static class ReadOnlyCollection
{
    /// <summary>
    /// Returns an empty, read-only collection that has the specified type argument.
    /// </summary>
    /// <typeparam name="T">
    /// The type to assign to the type parameter of the returned generic read-only collection.
    /// </typeparam>
    /// <returns>
    /// An empty, read-only collection whose type argument is T.
    /// </returns>
    public static IReadOnlyCollection<T> Empty<T>()
    {
        return CachedValueProvider<T>.Value;
    }

    /// <summary/>
    static class CachedValueProvider<T>
    {
        /// <summary/>
        public static readonly IReadOnlyCollection<T> Value = new T[0];
    }
}

像这样使用:

IReadOnlyCollection<int> empty = ReadOnlyCollection.Empty<int>();

答案 4 :(得分:0)

return new List<XElement>().AsReadOnly();