将generics类型对象转换为子类型

我的代码中有以下场景:

class Document {} class Track : Document {} class ViewListClickHandler { // I can't change that signature, it's provided by a library I use. protected override void click(object theList, int index) { // I here need to cast "theList" to IList where T : Document } } 

我现在的问题是(正如评论中所写):

如何将theList转换为类似IList where T : Document的类型IList where T : Document

在这种情况下的困难是,我可以获得任何类,在该列表中扩展Document 。 对我来说,我得到的也是一样的。 我只想将其转换为包含一些文档的列表。

编辑:

对不起,忘了提。 theList有时是一个对象,与IList兼容,有时是IList或者通常输入到Document其他子类型。

我需要在单行中做到这一点。 我有另一个例子,它不是IList,而是另一个通用类型的类,我无法循环。

你可以使用OfType :

 var documents = theList.OfType(); 

这里的问题是协方差和逆变。 对于子类型转换,您需要具有通用的协变接口。 IEnumerable和IQueryable就是一个很好的例子。 你唯一需要的是这个接口的每个方法只返回类型为T(协方差)的对象,或者如果接口方法只接收类型为T的对象(逆变),你的接口定义需要输入/输出字。 EX:

 // covariance public interface ICovarianct{ IEnumerable Get(); } // contravariance public interface Contravariant{ void Method(T arg) } 

然后在您的特定示例中,您不能使用强制转换,因为IList不是协变的。 你可以使用LINQ扩展,如:

 OfType() //to enumerate only the items of certain types. all.OfType() 

将返回集合中的所有文档

希望这有帮助!

只需调用(IList) theList或者如果元素不是Documents执行两步:首先将object theListIList 。 然后迭代每个元素并检查它是否是Document

你不能转换为开放的generics类型 – 为什么不直接转换为IList ? 它并不完全清楚,但似乎你说你只会用文件列表调用方法?

 //Provided that theList was either List or List or any class derived from Document. You can just cast using this statement List documents = theList as List;