Reputation: 1305
I have a bunch of classes that need to return properties as ReadOnlyCollection<T>
s, which works well when they're just List<T>
s, however, things get really sloppy with than list is inside a Dictionary<TKey, TValue>
.
================================================
For example, this is a typical List that I return as a ReadOnlyCollection:
private readonly List<string> _encryptionKeys;
public ReadOnlyCollection<string> EncryptionKeys => _encryptionKeys.AsReadOnly();
================================================
However, this is the convulation I need to do for a ReadOnlyDictionary<TKey, TValue>:
private readonly ReadOnlyDictionary<string, ReadOnlyCollection<string>> _attributes;
public ReadOnlyDictionary<string, ReadOnlyCollection<string>> Attributes => _attributes;
... using a temporary variable:
Dictionary<string, List<string>> attributes = new Dictionary<string, List<string>>();
... to which I add values and its lists, I then build my property:
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);
================================================
Anyone have any suggestions?
Upvotes: 0
Views: 242
Reputation: 6081
Linq can do the heavylifting for you.
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()));
Upvotes: 0
Reputation: 71364
Make it an extension method, then you don't have to think about it the whole time:
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())
));
}
Although, the constructor that takes IEnumerable<KeyValuePair>
is only available in .NET 5. So in earlier versions we would have to foreach
. This option may also be more performant as we pre-size the dictionary
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);
}
Just use it like you use the other AsReadOnly
extension.
Upvotes: 1