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