... and can I do it?
So I wanted to implement an EnumerableSubset class for dealing with pagination results within the API:
public interface IEnumerableSubset<T> : IEnumerable<T>{
int Total {get;}
}
public class ListSubset<T> : List<T>, IEnumerableSubset<T>{
public int Total {get;}
ListSubset(IEnumerable<T> items, int total){
AddRange(items);
Total = total;
}
}
So downcasting generics works with CLR enumerables like List:
public IEnumerable<IMyResultObject> GetResults(int skip, int top){
//return interface but pass class type for deserialization
var results = GetResults<MyResultObject>(skip,top);
//results is IEnumerable<MyResultObject>
return results;
}
but not for downcasting generics works with my type:
public IEnumerableSubset<IMyResultObject> GetResults(int skip, int top){
//return interface but pass class type for deserialization
var results = GetResults<MyResultObject>(skip,top);
//results is IEnumerableSubset<MyResultObject>
return results;
}
"Invalid Cast" compiler error.
I have to create a new instance of the ListSubset(results, results.Total) that has already been instanciated in GetResults.
So my question is: How does List manage to downcast the generic type and can I do that?
Thanks
CodePudding user response:
You have declared your interface to be invariant in T
. You should declare it to be covariant in T
, like IEnumerable
does:
public interface IEnumerableSubset<out T> : IEnumerable<T>
At that point, it should work.
For more information on generic variance in C#, see the Microsoft documentation.