将具体类强制转换为泛型接口,并将接口作为泛型类型会导致无效的强制转换异常

本文关键字:转换 异常 无效 泛型类型 泛型接口 接口 | 更新日期: 2023-09-27 18:30:41

>我已经搜索了几篇关于我所面临的问题的帖子,我在这里找到了最相似的主题

但是,这里我们在泛型接口转换中有一个类作为类型,并且正如我检查的那样,类 SqlCommand 继承自实现 IDbCommand 的 DbCommand。我的例子:我们有一个处理器类,假设它有方法进程。处理器包含一个属性,该属性是下面描述的泛型类型的接口。

public class Processor
{
IDbTools<IDbCommand> DbTools {get; set;}
public Processor() {}
public void Process()
{
    DbTools = (IDbTools<IDbCommand>)new Tools();
    DbTools.PrepareAndExecuteQuery();
}
}
public class Tools : IDbTools<SqlCommand>
{
    public void PrepareAndExecuteQuery(SqlCommand command);
}
public interface IDbTools<in TCommand>
    where TCommand: IDbCommand
{
    void PrepareAndExecuteQuery(TCommand command);
}

在此示例中,我们将收到一个 InvalidCastException,没有编译错误。我不明白为什么会发生这种情况,如果 SqlCommand 继承自 DbCommand 并且它实现了 IDbCommand。

我为使其工作而采用的方法如下所示:

public class Processor<TCommand>
    where TCommand: IDbCommand, new()
{
IDbTools<TCommand> DbTools {get; set;}
public Processor() {}
public void Process()
{
    DbTools = (IDbTools<TCommand>)new Tools();
    DbTools.PrepareQuery();
}
}
public class Tools : IDbTools<SqlCommand>
{
    void PrepareAndExecuteQuery(SqlCommand command);
}
public interface IDbTools<TCommand>
    where TCommand: IDbCommand
{
    void PrepareAndExecuteQuery(TCommand command);
}

所以我的问题是,为什么会这样。当然,如果我们实施

Tools : IDbTools<IDbCommand>

一切都会起作用,但为什么它不在这种情况下......

编辑:我正在 ideone.com 附加示例:代码,其中相同的代码仅用于将过去的目的复制到新项目中。附加的必需命名空间。

还添加了 in 子句,这并不能解决问题。

将具体类强制转换为泛型接口,并将接口作为泛型类型会导致无效的强制转换异常

您需要

使用 in 关键字声明您的IDbTools<>接口

public interface IDbTools<in TCommand>
    where TCommand: IDbCommand
{
    void PrepareAndExecuteQuery(TCommand command);
}

请参阅此处有关协方差和逆变的信息,Microsoft可以比我更好地解释它