I tried this route as well, converting Dictionary<string, List<Foo>>
to a ReadOnlyDictionary<string, IEnumerable<Foo>>
. While I was trying to convert to a read-only dictionary, the whole purpose of converting a List
to IEnumerable
is to make a read only collection. The problem with the OP's approach is:
Dictionary<string, List<string>> errors = new Dictionary<string, List<string>>();
errors["foo"] = new List<string>() { "You can't do this" };
Dictionary<string, IEnumerable<string>> readOnlyErrors = // convert errors...
readOnlyErrors["foo"] = new List<string>() { "I'm not actually read-only!" };
The appearance of IEnumerable<Foo>
makes you think this is read only and safe, when in fact it is not. After reading the question LINQ Convert Dictionary to Lookup a Lookup
object is more appropriate, because it allows you to:
Associate one key with multiple values
You cannot overwrite a key with a new value
// This results in a compiler error
lookUp["foo"] = new List<Foo>() { ... };
The "multiple values" are already defined as IEnumerable<T>
You can still use the same outer and inner loop algorithm to extract individual values:
ILookup<string, string> lookup = // Convert to lookup
foreach (IGrouping<string, string> grouping in lookup)
{
Console.WriteLine(grouping.Key + ":");
foreach (string item in grouping)
{
Console.WriteLine(" item: " + item);
}
}
Convert Dictionary<string, List<Foo>>
to ILookup<string, Foo>
It's a quick two-liner:
Dictionary<string, List<Foo>> foos = // Create and populate 'foos'
ILookup<string, Foo> lookup = foos.SelectMany(item => item.Value, Tuple.Create)
.ToLookup(p => p.Item1.Key, p => p.Item2);
Now you can use the same two-step loop as you would have with a Dictionary<string, IEnumerable<Foo>>
:
foreach (IGrouping<string, Foo> grouping in lookup)
{
string key = grouping.Key;
foreach (Foo foo in grouping)
{
// Do stuff with key and foo
}
}
Source: LINQ Convert Dictionary to Lookup
Converting to another Dictionary with an IEnumerable value is like trying to stuff a square peg into a round hole. The more appropriate, and safe way (from an object-oriented standpoint) is to convert your read/write Dictionary to a Lookup. This gives you the true intended safety of an object that is read-only (except for the Foo
items, which might not be immutable).
I would go so far as to say that most times when a ReadOnlyDictionary
is used, you could use ILookup
and get the same functionality.