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

Sté*_*écy 31 c# linq

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

var empty = Enumerable.Empty<string> ();
Run Code Online (Sandbox Code Playgroud)

是否有像这样容易创建空字典?

Ste*_*fan 26

没有没有相应的......

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

您不能将此转换为非读取结构,例如,IDictionary<TKey, TValue>或者Dictionary<TKey, TValue>因为返回的实例可能会在以后修改,因此会使目的无效...

  • 是的,有:`ImmutableDictionary &lt;TKey,TValue&gt; .Empty` (4认同)

emp*_*mpi 9

怎么了new Dictionary<string, string>()

  • 空字典是可变的,并且可能会消耗内存,因为您多次实例化它.他可能想要一个只读空IDictionary <string,string>的引用. (4认同)
  • c# 中存在 `.Empty` 构造的原因是为了提供一种方便的方式来获取对象的空表示的静态、缓存、不可变实例,可以在需要此类对象的地方使用它,但不能真正用过,在代码中。如果您每次只需要一个空的占位符时都构建一个新对象,而对于一个您并不真正使用的对象,那就违背了整个概念的要点。 (2认同)

Mla*_* B. 7

回到2019年,有一种方法可以实现此目标,方法是:

ImmutableDictionary<TKey, TValue>.Empty
Run Code Online (Sandbox Code Playgroud)

可以在这里找到更多信息(最后几篇文章):https : //github.com/dotnet/corefx/issues/25023


Mar*_*age 6

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

public class MyConfiguration
{
    public IReadOnlyDictionary<string, string> MyProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果从未配置该属性,该怎么办?然后MyPropertynull.避免意外NullReferenceException情况的一个好方法是使用空字典初始化属性:

public class MyConfiguration
{
    public IReadOnlyDictionary<string, string> MyProperty { get; set; }
        = new Dictionary<string, string>();
}
Run Code Online (Sandbox Code Playgroud)

缺点是每次分配都MyConfiguration需要分配一个空字典.要避免这种情况,您需要类似的东西Enumerable.Empty<T>(),即缓存的空只读字典.

有两种方法可以实现这一目标.第一种是依赖System.Collections.Immutable.一个ImmutableDictionary<TKey, TValue>实现IReadOnlyDictionary<TKey, TValue>,它有一个Empty你可以使用的字段:

IReadOnlyDictionary<string, string> empty = ImmutableDictionary<string, string>.Empty;
Run Code Online (Sandbox Code Playgroud)

或者你可以实现自己的空的只读字典,类似于Enumerable.Empty<T>()Array.Empty<T>().注意空值不再是一个字段,而且该类不是通用的.相反,它是一种通用方法.这需要两个班级.

第一个类是"隐藏的",可以是内部的:

internal static class EmptyReadOnlyDictionary<TKey, TValue>
{
    public static readonly IReadOnlyDictionary<TKey, TValue> Instance
        = new Dictionary<TKey, TValue>();
}
Run Code Online (Sandbox Code Playgroud)

第二个类使用第一个类但隐藏在IReadOnlyDictionary<TKey, TValue>接口后面:

public static class ReadOnlyDictionary
{
    public static IReadOnlyDictionary<TKey, TValue> Empty<TKey, TValue>()
        => EmptyReadOnlyDictionary<TKey, TValue>.Instance;
}
Run Code Online (Sandbox Code Playgroud)

用法:

IReadOnlyDictionary<string, string> empty = ReadOnlyDictionary.Empty<string, string>();
Run Code Online (Sandbox Code Playgroud)

对于这两种解决方案,每个不同的TKey和的组合只有一个空的字典实例TValue.


Mis*_*sky 6

在 .NET 8 预览版中,可以Dictionary通过以下方式创建空的:

ReadOnlyDictionary<TKey, TValue>.Empty;
Run Code Online (Sandbox Code Playgroud)

这种方式不使用内存,并且比使用关键字启动速度更快new