如何创建空的 IReadOnlyCollection

问题描述 投票:0回答:6

我正在为 MultiValueDictionary 创建一个扩展方法来封装频繁的

ContainsKey
检查,我想知道创建空
IReadOnlyCollection
的最佳方法是什么?

到目前为止我使用的是

new List<TValue>(0).AsReadOnly()
,但一定有更好的方法,相当于
IEnumerable
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;
}
c# .net readonly-collection multi-value-dictionary
6个回答
42
投票

编辑:新的.Net 4.6添加了一个API来获取空数组:

Array.Empty<T>
并且数组实现了
IReadOnlyCollection<T>
。这也减少了分配,因为它只创建一次实例:

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

我最终做的是使用 Enumerable.Empty

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

用途:

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

8
投票

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


4
投票

我不认为有像

Enumerable.Empty
这样的只读集合,但是:

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

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


4
投票

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

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

您可以选择缓存结果,因为它是空数组上的

ReadOnlyCollection
,无论您有多少个实例,它总是相同的。


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

0
投票

现在,使用.NET8.0我们可以通过以下方式实现:

return ReadOnlyCollection<T>.Empty;
© www.soinside.com 2019 - 2024. All rights reserved.