I've these linq from
clauses in a sentence:
IEnumerable<T> collection = //...;
IEnumerable<PropertyInfo> propertiesToFlat = typeof(T).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(FlattenAttribute)));
var accessorFieldsbyLevel = from element in collection
from property in propertiesToFlat
from internalField in (IEnumerable<object>)(typeof(T).GetProperty(property.Name).GetValue(element))
//...
This sentence compiles. However I need to substitute the next from
clause:
from internalField in (IEnumerable<object>)(typeof(T).GetProperty(property.Name).GetValue(element))
by this one:
from internalField in (IEnumerable)(typeof(T).GetProperty(property.Name).GetValue(element))
So, I'm only changing (IEnumerable<object>)
cast by this other one (IEnumerable)
.
Then the compiler tells me:
Error 1 An expression of type 'System.Collections.IEnumerable' is not allowed in a subsequent from clause in a query expression with source type 'System.Collections.Generic.IEnumerable'. Type inference failed in the call to 'SelectMany'.
I've absolutly no idea what's happening. What's wrong here?
[EDIT]
I suppose the problem is because collection
and propertiesToFlat
are a generic collections, I'm trying to set a from
clause with a non-generic IEnumerable
.
How could I solve that?
Basically, LINQ contains very few operations which work on non-generic collections. There's no Enumerable.Where(IEnumerable, ...)
for example - only Enumerable.Where<T>(IEnumerable<T>, ...)
.
The simplest way to fix this is to use an explicitly typed range variable in your query, which will insert a call to Enumerable.Cast<T>(IEnumerable)
:
from object internalField in (IEnumerable)(typeof(T).GetProperty(property.Name).GetValue(element))
That's equivalent to:
from internalField in
((IEnumerable)(typeof(T).GetProperty(property.Name).GetValue(element))
.Cast<object>()
See more on this question at Stackoverflow