[英]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()
但必须有更好的方法,相当于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;
}
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.