我已经搜索了几个关于我面临的问题的帖子,我发现了最类似的主题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子句,而不是解决问题。
答案 0 :(得分:1)
您需要使用in keyword
声明IDbTools<>
界面
public interface IDbTools<in TCommand>
where TCommand: IDbCommand
{
void PrepareAndExecuteQuery(TCommand command);
}
请参阅此处有关Covariance and Contravariance的信息,Microsoft可以比我更好地解释它