c# - 将具体类转换为具有通用类型接口(interface)的通用接口(interface)会导致无效转换异常

标签 c# generics interface casting

我搜索了几个关于我面临的问题的帖子,我找到了最相似的主题 here

但是,这里我们有一个类作为通用接口(interface)转换中的类型,正如我检查的那样,类 SqlCommand 继承自 DbCommand,它实现了 IDbCommand。 我的例子: 我们有一个 Processor 类,假设它有方法 Process。 处理器包含一个属性,它是下面描述的通用类型的接口(interface)。

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 附上示例:Code相同的代码在哪里只是为了将过去的目的复制到新项目中。附加所需的命名空间。

还添加了 in 子句,但这并没有解决问题。

最佳答案

您需要申报您的 IDbTools<>in keyword 的接口(interface)

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

在这里查看关于 Covariance and Contravariance 的信息, Microsoft 可以比我更好地解释它

关于c# - 将具体类转换为具有通用类型接口(interface)的通用接口(interface)会导致无效转换异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34812021/

相关文章:

c# - 处理 XML 更改的好方法

c# - 图形 - DrawLine - 画线并移动它

c# - 为什么 is 关键字需要非空表达式?

java - 在具体的 JPA 类之间共享 Java 实现的最佳方法是什么?

c++ - 在 Linux 上的 C++ 应用程序中的 C 接口(interface)上为函数别名

C# MySQL 求和 InvalidCastException

java - 如何以通用方式访问 Java 构造函数?

java - 当参数作为通用 ArrayList<?> 传递时如何添加

c# - 如何使用 Unity.WebApi 通过接口(interface)实例访问类属性

android - 在 2 个以上的 fragment 之间进行通信