带有 ReadOnlyCollection<T> 的 ReadOnlyDictionary<TKey, TValue>

问题描述

我有一堆类需要将属性作为 ReadOnlyCollection<T> 返回,当它们只是 List<T>效果很好,但是,由于列表位于 { 中,所以事情变得非常草率{1}}。

================================================ =

例如,这是我作为 ReadOnlyCollection 返回的典型列表:

Dictionary<TKey,TValue>

================================================ =

然而,这是我需要为 ReadOnlyDictionary 做的转换:

    private readonly List<string> _encryptionKeys;
    public ReadOnlyCollection<string> EncryptionKeys => _encryptionKeys.AsReadOnly();

... 使用临时变量:

    private readonly ReadOnlyDictionary<string,ReadOnlyCollection<string>> _attributes;
    public ReadOnlyDictionary<string,ReadOnlyCollection<string>> Attributes => _attributes;

... 我向其中添加值及其列表,然后构建我的属性

        Dictionary<string,List<string>> attributes = new Dictionary<string,List<string>>();

================================================ =

大家有什么建议吗?

解决方法

把它做成扩展方法,那你就不用一直想了:

public static ReadOnlyDictionary<TKey,ReadOnlyCollection<TValue>> AsReadOnly<TKey,TValue>(this Dictionary<TKey,List<TValue>> source)
{
    return new ReadOnlyDictionary<TKey,ReadOnlyCollection<TValue>>(
        new Dictionary<TKey,ReadOnlyCollection<TValue>>(
        source.Select(kvp =>
            new KeyValuePair<TKey,ReadOnlyCollection<TValue>>(kvp.Key,kvp.Value.AsReadOnly())
    ));
}

虽然,采用 IEnumerable<KeyValuePair> 的构造函数仅在 .NET 5 中可用。因此在早期版本中,我们将不得不 foreach。当我们预先调整字典的大小时,此选项也可能更高效

public static ReadOnlyDictionary<TKey,List<TValue>> source)
{
    var dict = new Dictionary<TKey,ReadOnlyCollection<TValue>>(source.Count);
    foreach (var kvp in source)
        dict[kvp.Key] = kvp.Value.AsReadOnly();
    return new ReadOnlyDictionary<TKey,ReadOnlyCollection<TValue>>(dict);
}

就像使用其他 AsReadOnly 扩展一样使用它。

,

Linq 可以为您完成繁重的工作。

Dictionary<string,List<string>> input = new Dictionary<string,List<string>>();
ReadOnlyDictionary<string,ReadOnlyCollection<string>> output = new ReadOnlyDictionary<string,ReadOnlyCollection<string>>(dict.ToDictionary(kv => kv.Key,kv => kv.Value.AsReadOnly()));