Casting a generic typed object per subtype
I have the following script in my code:
class Document
{}
class Track : Document
{}
class ViewListClickHandler
{
// I can't change that signature, it provided by a library I use.
protected override void click(object theList, int index)
{
// I here need to cast "theList" to IList<T> where T : Document
}
}
Now my question (as written in the comment):
How can I apply this theList
to a type type IList<T> where T : Document
?
The difficulty in this case is that I can get any class by extending Document
in this list. And this is the same for me what I get. I just want to pass it to a list containing some documents.
EDIT:
Sorry forgot to mention this. theList
sometimes is an object compatible with IList<Document>
, sometimes IList<Track>
or generally typed by another subtype Document
.
I need to do this in one layer. I have another example where it is not an IList but another typically typed class where I cannot loop.
source to share
The problem here is covariance and contravariance. For casting subtypes, you need to have a common covariant interface. IEnumerable and IQueryable are good examples of this. The only thing you need is that each method of this interface returns objects of type T (covariance) or if the interface methods only receive an object of type T (contravariance) and the in / out word is required to define the interface. EX:
// covariance
public interface ICovarianct<out T>{
IEnumerable<T> Get();
}
// contravariance
public interface Contravariant<in T>{
void Method(T arg)
}
Then, in your specific example, you cannot use casting because IList is not a covariate. You can use LINQ extensions like:
OfType<T>() //to enumerate only the items of certain types.
all.OfType<Document>()
will return all documents in the collection
Hope for this help!
source to share