I am using using Microsoft .NET Framework 4.0.
I have run into this using Aggregate on a Dictionary<T, List<T>> to extract the set of type T values used across all type List<T> lists in the dictionary. Here is the simplest case I could come up with that exhibits the same behaviour.
First, as the documentation states, the following does work:
var set = new HashSet<int>();
var list = new LinkedList<int>();
var newSet = set.Union(list);
That is, I can call Union on a HashSet with a List as the argument (since it implements IEnumerable).
Whereas, the equivalent expression within a Func argument of the LINQ Aggregate expression produces an error (precompiler at least):
new List<int>[] { new List<int>() }.Aggregate(new HashSet<int>(), (acc, list) => acc.Union(list));
It expects the argument of Union to be HashSet, and will cooperate if it is given one, contrary to its behaviour outside LINQ/Func expressions.
The real world example I was using when I came across the problem was:
public AdjacencyListGraph(Dictionary<TVertex, LinkedList<TVertex>> adjacencyList)
{
var vertices = adjacencyList.Aggregate(new HashSet<TVertex>(),
(vertices, list) => vertices.Union(list.Value));
}
Which complains that it cannot convert IEnumerable<TVertex> to HashSet<TVertex>…
The problem actually lies in trying to replace the accumulator type of HashSet with the IEnumerable, .Union method doesn’t add items to HashSet, but returns the new IEnumerable on the resulting union.
You should change your code to the following:
or