【发布时间】:2019-05-22 20:44:06
【问题描述】:
我有以下课程:
public interface IA
{
}
public class A : IA
{
}
public interface IB<T> where T : IA
{
Foo SomeMethod(T someObject);
}
public abstract class BBase<T> : IB<T> where T : IA
{
// implements SomeMethod();
}
public class BSpecific: BBase<A>
{
// overrides SomeMethod();
}
这会在运行时引发异常:
var foo = ((IB<IA>)Activator.CreateInstance("BSpecific"));
System.InvalidCastException:无法将 BSpecific 类型的对象转换为 IB'1[IA] 类型
转换为 BBase 会引发相同的异常。
Why I am getting the Unable to cast exception here 是一个非常相似的场景,但推荐的答案(使用逆变/“out T”)不适用于我的情况,因为 SomeMethod() 采用 T 参数。
我不太确定为什么我需要逆变(或者逆变到底是做什么的)。类型和类都被转换为它们实现的接口,所以......?
还有什么我可以做的吗?
(包含转换的代码被包含BSpecific类的项目用作引用,但它本身不知道BSpecific是什么,所以转换是强制性的。)
【问题讨论】:
-
你试过 IB
foo = Activator.CreateInstance("BSpecific") as IB ; ? foo 为空吗?也许您应该提供完整的类名,例如:“Namespace.BSpecific”?或者也许你应该尝试使用 Type.GetType("BSpecific") 创建一个类型,然后在激活器中使用这个类型? -
你试过了吗?看起来您的 SomeMethod 接受 T 作为函数参数,它与接口的 T 或基类的 T 无关
-
@AdamJachocki 它为空,设置断点告诉我 BSpecific 的实例已正确创建,但随后转换失败。
-
@SKLTFZ 我试过了,编译时错误出现在 SomeMethod() 上,因为 T“必须是逆变有效但协变”。
-
没有安全的方法来进行这种转换 -
BSpecific实现IB<A>所以它的SomeMethod方法只接受A的实例,而不接受任何IA实例。