[英]Generic casting
I have this generic class 我有这个普通班
public abstract class BaseExportCommand<T> where T : EditableEntity, new()
{
....
}
and I have this derived class 我有这个派生类
public class MessageExportCommand : BaseExportCommand<Message>
{
.....
}
Where Message inherits from EdittableEntity 消息从EdittableEntity继承的地方
public class Message : EditableEntity
{
...
}
Now, when I try to do this statement 现在,当我尝试执行此语句时
BaseExportCommand<EditableEntity> myValue = new MessageExportCommand ();
I got the following error: 我收到以下错误:
Cannot convert type 'MessageExportCommand' to 'BaseExportCommand<EditableEntity>'
Any idea why? 知道为什么吗?
Any idea why?
知道为什么吗?
Yes. 是。 Your generic type isn't covariant in
T
. 您的通用类型在
T
不是协变的。
We can't tell immediately whether it should be or not. 我们无法立即判断是否应该这样做。 For example, suppose it looked like this:
例如,假设它看起来像这样:
public abstract class BaseExportCommand<T> where T : EditableEntity, new()
{
public abstract DoSomethingWithEntity(T entity);
}
Then suppose you could write: 然后假设您可以编写:
BaseExportCommand<EditableEntity> myValue = new MessageExportCommand();
EditableEntity entity = new SomeEditableEntity();
myValue.DoSomethingWithEntity(entity);
... whereas MessageExportCommand
only expects DoSomethingWithEntity(Message)
. ...而
MessageExportCommand
只需要DoSomethingWithEntity(Message)
。
It's safe if you're only using T
as an output from BaseExportCommand<T>
, but unfortunately C# doesn't let you declare covariant type parameters for classes - only for interfaces and delegates. 如果仅将
T
用作BaseExportCommand<T>
的输出是安全的,但是不幸的是C#不允许您为类声明协变类型参数-仅针对接口和委托。 So you could potentially write: 因此,您可能会写:
// Note the "out" part, signifying covariance
public interface IExportCommand<out T> where T : EditableEntity, new()
Then: 然后:
IExportCommand<EditableEntity> = new MessageExportCommand();
... but it depends on what members were declared in the interface. ...但是这取决于在接口中声明了哪些成员。 If you try to use
T
in any "input" positions, the compiler will notice and prevent you from declaring T
covariantly. 如果尝试在任何“输入”位置使用
T
,则编译器会注意到并阻止您协变地声明T
See Variance in Generic Types in MSDN for more details, as well as Eric Lippert's blog posts on the topic (settle back and relax, there's a lot to read). 有关更多详细信息,请参见MSDN中的“泛型类型”中的Variance ,以及有关该主题的Eric Lippert的博客文章 (安顿下来,放松一下,有很多书要读)。
This will only work if you declare T
as co-variant: 仅当您将
T
声明为协变量时,这才有效:
public abstract class BaseExportCommand<out T> where T : EditableEntry, new()
{
...
}
Co-variant means, that you can use it for T
or any class that inherits from T
. 协变意味着,您可以将其用于
T
或从T
继承的任何类。
Also see the Covariance and Contravariance FAQ . 另请参阅协方差和协方差常见问题解答 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.