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