0

I have Class B, C, and D inherited from Interface IA. Now I've got IQueryable<B>, IQueryable<C>, and IQueryable<D> that requires a method to do some stuff with some of the properties in IA.

public IQueryable<T> DoStuff<T>(IQueryable<IA> samples) where T: IA{
    // something that filters samples. Ommited

    return samples.Select(s => (T)s).AsQueryable(); // works
    //return (IQueryable<T>)samples; //InvalidCastException
}

var samples; // samples can be IQueryable<B>, IQueryable<C>, or IQueryable<D>
samples = DoStuff(samples); 

Two questions:

  1. Why didn't it cast with IQueryable<T>? And it did cast when looping and casting one by one.
  2. Initially, B, C, and D inherited from class A. That didn't work because I could not cast down a class from A to B, C, D. Then I changed A to IA. However, I've read some people said that when you need to cast down an interface to its concrete implementation, you have a design problem. Do I need to avoid casting down here? If so, what's a good approach to achieve the goal?
michal.jakubeczy
  • 8,221
  • 1
  • 59
  • 63
Quentin
  • 1,310
  • 18
  • 30
  • 1
    The duplicate I suggested actually pre-dates co-variance being added in C# 4. See [this related question](http://stackoverflow.com/questions/12454794/why-covariance-and-contravariance-do-not-support-value-type) - you can resolve by adding `class` to your type constraint (i.e `where T : class, IA`). – Charles Mager Jun 22 '16 at 13:47
  • @CharlesMager Thanks! – Quentin Jun 22 '16 at 14:01
  • Something is wrong about the duplicate... this question is talking about `Base-->Derived` while the "duplicate" talks about `Derived-->Base`, more so, it should just accept an `IQueryable` as parameter and not bother with any casting. – grek40 Nov 13 '17 at 12:12

0 Answers0