ReadOnlyDictionary<TKey, TValue> 与 ReadOnlyCollection<T>

ReadOnlyDictionary<TKey, TValue> with a ReadOnlyCollection<T>

我有一堆 类 需要 return 属性作为 ReadOnlyCollection<T>s,当它们只是 List<T>s 时效果很好,但是,事情比列表在 Dictionary<TKey, TValue>.

中变得非常草率

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

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

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

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

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

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

...使用临时变量:

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

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

        Dictionary<string, ReadOnlyCollection<string>> readonlyListDictionary = new Dictionary<string, ReadOnlyCollection<string>>();
        foreach (string key in attributes.Keys)
            readonlyListDictionary.Add(key, attributes[key].AsReadOnly());
        _attributes = new ReadOnlyDictionary<string, ReadOnlyCollection<string>>(readonlyListDictionary);

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

有人有什么建议吗?

让它成为一个扩展方法,那么你就不用一直想着它了:

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, ReadOnlyCollection<TValue>> AsReadOnly<TKey, TValue>(this Dictionary<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()));