简体   繁体   English

如何创建一个空的 IReadOnlyCollection

[英]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 ?.我正在为MultiValueDictionary创建一个扩展方法来封装频繁的ContainsKey检查,我想知道创建空的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到目前为止我使用的是new List<TValue>(0).AsReadOnly()但必须有更好的方法,相当于IEnumerableEnumerable.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;
}

EDIT: The new .Net 4.6 adds an API to get an empty array: Array.Empty<T> and arrays implement IReadOnlyCollection<T> . 编辑:新的.Net 4.6添加了一个API来获取一个空数组: Array.Empty<T>和数组实现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] : 我最终做的是使用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]); }
        }
    }
}

Usage: 用法:

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

I don't think there's anything like Enumerable.Empty for read-only collections, but: 对于只读集合,我认为没有像Enumerable.Empty这样的东西,但是:

  • List<T> already implements IReadOnlyCollection<T> so you can avoid one object allocation by not calling AsReadOnly() and simply casting the list instead. List<T>已经实现了IReadOnlyCollection<T>因此您可以通过不调用AsReadOnly()并简单地转换列表来避免一个对象分配。 This is less "safe" in theory but hardly matters in practice. 这在理论上不那么“安全”,但在实践中几乎不重要。

  • Alternatively, you could cache the returned ReadOnlyCollection to avoid any object allocation whatsoever (except for the cached object). 或者,您可以缓存返回的ReadOnlyCollection以避免任何对象分配(缓存对象除外)。

As far as I know there is no built in way(Interested to know if one). 据我所知,没有内置方式(有兴趣知道是否有)。 That said, you can use the following: 也就是说,您可以使用以下内容:

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

Optionally you can cache the results as it is a ReadOnlyCollection over empty array, It will always be the same no matter how many instances you have. 您可以选择将结果缓存为空数组的ReadOnlyCollection ,无论您拥有多少个实例,它都将始终相同。

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

How's about this which has a similar syntax to Enumerable.Empty: 如何使用与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];
    }
}

Used like this: 像这样使用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM