簡體   English   中英

將泛型類型對象轉換為子類型

[英]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 theListIList<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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM