簡體   English   中英

泛型轉換

[英]Generic casting

我有這個普通班

public abstract class BaseExportCommand<T> where T : EditableEntity, new()
{
....
}

我有這個派生類

public class MessageExportCommand : BaseExportCommand<Message> 
{
 .....
}

消息從EdittableEntity繼承的地方

public class Message : EditableEntity
{
...
}

現在,當我嘗試執行此語句時

BaseExportCommand<EditableEntity> myValue = new MessageExportCommand ();

我收到以下錯誤:

Cannot convert type 'MessageExportCommand' to 'BaseExportCommand<EditableEntity>'   

知道為什么嗎?

知道為什么嗎?

是。 您的通用類型在T不是協變的。

我們無法立即判斷是否應該這樣做。 例如,假設它看起來像這樣:

public abstract class BaseExportCommand<T> where T : EditableEntity, new()
{
    public abstract DoSomethingWithEntity(T entity);
}

然后假設您可以編寫:

BaseExportCommand<EditableEntity> myValue = new MessageExportCommand();
EditableEntity entity = new SomeEditableEntity();
myValue.DoSomethingWithEntity(entity);

...而MessageExportCommand只需要DoSomethingWithEntity(Message)

如果僅將T用作BaseExportCommand<T>輸出是安全的,但是不幸的是C#不允許您為類聲明協變類型參數-僅針對接口和委托。 因此,您可能寫:

// Note the "out" part, signifying covariance
public interface IExportCommand<out T> where T : EditableEntity, new()

然后:

IExportCommand<EditableEntity> = new MessageExportCommand();

...但是這取決於在接口中聲明了哪些成員。 如果嘗試在任何“輸入”位置使用T ,則編譯器會注意到並阻止您協變地聲明T

有關更多詳細信息,請參見MSDN中的“泛型類型”中的Variance ,以及有關該主題的Eric Lippert的博客文章 (安頓下來,放松一下,有很多書要讀)。

僅當您將T聲明為協變量時,這才有效:

public abstract class BaseExportCommand<out T> where T : EditableEntry, new()
{
    ...
}

協變意味着,您可以將其用於T或從T繼承的任何類。

另請參閱協方差和協方差常見問題解答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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