使用 Linq to 对象,如何轻松创建<字符串、字符串>的空字典

本文关键字:字符串 字典 创建 to Linq 对象 何轻松 使用 | 更新日期: 2023-09-27 18:32:58

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

var empty = Enumerable.Empty<string> ();

有没有像这样容易地创建空字典的等效项?

使用 Linq to 对象,如何轻松创建<字符串、字符串>的空字典

回到2019年,有一种方法可以实现这一点,使用:

ImmutableDictionary<TKey, TValue>.Empty

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

不,

没有等价物...

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

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

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

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

public class MyConfiguration
{
    public IReadOnlyDictionary<string, string> MyProperty { get; set; }
}

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

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

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

ReadOnlyDictionary<TKey, TValue>.Empty;

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

当键和值具有相同的类型(例如:字符串(时:

Enumerable.Empty<string>().ToDictionary(x=>x, x=>x)
Enumerable.Empty<KeyValuePair<string, object>>().ToDictionary(kvp => kvp.Key, kvp => kvp.Value)