[英]Casting generic typed object to subtype
我的代碼中有以下場景:
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<T> where T : Document
}
}
我現在的問題是(正如評論中所寫):
如何將theList
轉換為類似IList<T> where T : Document
的類型IList<T> where T : Document
?
在這種情況下的困難是,我可以獲得任何類,在該列表中擴展Document
。 對我來說,我得到的也是一樣的。 我只想將其轉換為包含一些文檔的列表。
編輯:
對不起,忘了提一下。 theList
有時是一個對象,與IList<Document>
兼容,有時是IList<Track>
或者通常輸入到Document
其他子類型。
我需要在單行中做到這一點。 我有另一個例子,它不是IList,而是另一個通用類型的類,我無法循環。
你可以使用OfType :
var documents = theList.OfType<Document>();
這里的問題是協方差和逆變。 對於子類型轉換,您需要具有通用的協變接口。 IEnumerable和IQueryable就是一個很好的例子。 你唯一需要的是這個接口的每個方法只返回類型為T(協方差)的對象,或者如果接口方法只接收類型為T的對象(逆變),你的接口定義需要輸入/輸出字。 EX:
// covariance
public interface ICovarianct<out T>{
IEnumerable<T> Get();
}
// contravariance
public interface Contravariant<in T>{
void Method(T arg)
}
然后在您的特定示例中,您不能使用強制轉換,因為IList不是協變的。 你可以使用LINQ擴展,如:
OfType<T>() //to enumerate only the items of certain types.
all.OfType<Document>()
將返回集合中的所有文檔
希望這有幫助!
只需調用(IList<Document>) theList
或者如果元素不是Documents
執行兩步:首先將object theList
為IList<object>
。 然后迭代每個元素並檢查它是否是Document
。
你不能轉換為開放的泛型類型 - 為什么不轉換為IList<Document>
? 它並不完全清楚,但似乎你說你只會用文件列表調用方法?
//Provided that theList was either List<Track> or List<Document> or any class derived from Document. You can just cast using this statement
List<Document> documents = theList as List<Document>;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.