我搜索了几个关于我面临的问题的帖子,我找到了最相似的主题 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/