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

时间:2016-01-15 13:20:39

标签: c# generics interface casting

我已经搜索了几个关于我面临的问题的帖子,我发现了最类似的主题here

但是,这里我们有一个类作为通用接口转换类型,并且我检查类SqlCommand继承自实现IDbCommand的DbCommand。 我的例子: 我们有一个Processor类,让我们说有方法Process。 处理器包含一个属性,它是下面描述的泛型类型的接口。

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子句,而不是解决问题。

1 个答案:

答案 0 :(得分:1)

您需要使用in keyword

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

请参阅此处有关Covariance and Contravariance的信息,Microsoft可以比我更好地解释它