使用Linq对象,如何轻松地创建的空字典?

要创建空序列,请使用以下内容

var empty = Enumerable.Empty (); 

有没有像这样容易创建一个空字典?

不,没有相应的……

Enumerable.Empty()的目的是返回空数组的“缓存”实例。 因此,您可以避免创建新数组的开销( return new T[0]; )。

你不能将它转换为非读取结构,如IDictionaryDictionary因为返回的实例可能会在以后被修改,因此会使目的无效……

new Dictionary()什么问题?

我假设(至少现在5年后) 空字典真的意味着空的只读字典 。 此结构与空的可枚举序列一样有用。 例如,您可能有一个具有字典属性(想想JSON)的配置类型,一旦配置它就无法修改:

 public class MyConfiguration { public IReadOnlyDictionary MyProperty { get; set; } } 

但是,如果从未配置该属性该怎么办? 然后MyPropertynull 。 避免意外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(); 

对于这两种解决方案, TKeyTValue每个不同组合只有一个空字典实例。

当键和值具有相同的类型时(例如:string):

 Enumerable.Empty().ToDictionary(x=>x, x=>x) 
 Enumerable.Empty>().ToDictionary(kvp => kvp.Key, kvp => kvp.Value)