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