繁体   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