要创建一个空序列,请使用以下
var empty = Enumerable.Empty<string> ();
有没有类似的方法可以像这样轻松地创建一个空字典?
回到 2019 年,有一种方法可以实现这一点,使用:
ImmutableDictionary<TKey, TValue>.Empty
更多信息可以在这里找到(最后几篇文章):https ://github.com/dotnet/corefx/issues/25023
不,没有等价物...
的目的Enumerable.Empty<T>()
是返回一个空数组的“缓存”实例。因此,您可以避免创建新数组 ( return new T[0];
) 的开销。
您不能将其转换为非只读结构,如 a IDictionary<TKey, TValue>
orDictionary<TKey, TValue>
因为返回的实例可能会在以后被修改,因此会使目的无效......
有什么问题new Dictionary<string, string>()
?
我假设(至少现在 5 年后)空字典真的意味着空的只读字典。这种结构与空的可枚举序列一样有用。例如,您可能有一个配置类型,它具有一个字典属性(想想 JSON),一旦配置就无法修改:
public class MyConfiguration
{
public IReadOnlyDictionary<string, string> MyProperty { get; set; }
}
但是,如果该属性从未配置过怎么办?然后MyProperty
是null
。避免意外的一个很好的解决方案NullReferenceException
是使用空字典初始化属性:
public class MyConfiguration
{
public IReadOnlyDictionary<string, string> MyProperty { get; set; }
= new Dictionary<string, string>();
}
缺点是每次分配都MyConfiguration
需要分配一个空字典。为避免这种情况,您需要类似于 的Enumerable.Empty<T>()
内容,即缓存的空只读字典。
有两种方法可以实现这一点。第一个是依赖System.Collections.Immutable。一个ImmutableDictionary<TKey, TValue>
实现IReadOnlyDictionary<TKey, TValue>
,它有一个Empty
可以使用的字段:
IReadOnlyDictionary<string, string> empty = ImmutableDictionary<string, string>.Empty;
或者您可以实现自己的空只读字典,类似于Enumerable.Empty<T>()
and Array.Empty<T>()
。请注意空值如何不再是一个字段,并且该类不是通用的。相反,它是一种通用方法。这需要两个类。
第一类是“隐藏的”,可以是内部的:
internal static class EmptyReadOnlyDictionary<TKey, TValue>
{
public static readonly IReadOnlyDictionary<TKey, TValue> Instance
= new Dictionary<TKey, TValue>();
}
第二个类使用第一个类,但将其隐藏在IReadOnlyDictionary<TKey, TValue>
接口后面:
public static class ReadOnlyDictionary
{
public static IReadOnlyDictionary<TKey, TValue> Empty<TKey, TValue>()
=> EmptyReadOnlyDictionary<TKey, TValue>.Instance;
}
用法:
IReadOnlyDictionary<string, string> empty = ReadOnlyDictionary.Empty<string, string>();
TKey
对于这两种解决方案,对于 和 的每个不同组合,只有一个空字典实例TValue
。
当 key 和 value 具有相同的类型时(例如:字符串):
Enumerable.Empty<string>().ToDictionary(x=>x, x=>x)
Enumerable.Empty<KeyValuePair<string, object>>().ToDictionary(kvp => kvp.Key, kvp => kvp.Value)