BaltoStar
BaltoStar

Reputation: 8987

C# LINQ filter IEnumerable<IX> and express as IEnumerable<X:IX>

Apparently it's not possible to cast WhereEnumerableIterator<IX> to IEnumerable<X:IX>

public interface IX 

public class X1 : IX 
public class X2 : IX

public void Method1(IEnumerable<IX> arg)
{
    var filtered = arg.Where(e => e.GetType() == typeof(X2));
    // filtered will be of type WhereEnumerableIterator<IX>
    Method2(filtered as IEnumerable<X2>);
}

public void Method2(IEnumerable<X2> arg) 
{
    // at runtime arg will be null
}

Apparently the CLR is unable to cast WhereEnumerableIterator<IX> to IEnumerable<X2> and sets result null ( somewhat mysteriously ).

It seems logical that a filter could be applied to IEnumerable<IX> and the result expressed as IEnumerable<X:IX> ( without actually enumerating ).

But how to do this ?

Upvotes: 3

Views: 218

Answers (1)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34199

It happens, because filtered is IEnumerable<IX> (even though it contains only items of X2 after filtering) and cannot be casted directly to IEnumerable<X2>.
You could do this and cast your IEnumerable:

var filtered = arg.Where(e => e.GetType() == typeof(X2)).Cast<X2>();
// filtered will be of type WhereEnumerableIterator<X2> now
Method2(filtered);

But you can just use Enumerable.OfType to filter an IEnumerable based on the type of its elements:

public void Method1(IEnumerable<IX> arg)
{
    var filtered = arg.OfType<X2>();
    Method2(filtered);
}

public void Method2(IEnumerable<X2> arg) 
{

}

Upvotes: 6

Related Questions