需要注意的是ClassB 和ShimClassB 没有基类-派生类关系。所以你正在做的演员,可能不会完全符合你的期望。由于 Microsoft.Fakes 为您提供了用户定义的转换,您会看到隐式转换正常工作。
您的ShimClassB 继承自ShimBase<T>,其中T 是ClassB。这个类有一个方法可以在ShimClassB 和ClassB 之间引入一个用户定义的隐式转换。
public static implicit operator T(ShimBase<T> shim)
当你尝试做的时候。
public ClassA(object someInstance)
{
PropertyB = (ClassB)someInstance;
}
您不能强制转换为 ClassB,因为在 object 和 ClassB 之间没有定义转换。
来自 C# 编程语言规范 6.2.4 显式引用转换:
为了在运行时成功进行显式引用转换,值
源操作数必须为 null,或者对象的实际类型
源操作数引用的必须是可以转换的类型
通过隐式引用转换到目标类型(第 6.1.6 节)
或拳击转换(§6.1.7)。如果显式引用转换
失败,抛出 System.InvalidCastException。
您会发现,如果您的代码有中间转换,它将不再抛出 InvalidCastException 但这不是最终解决方案,因为您不希望在构造函数中对 Shim 进行转换:
public ClassA(object someInstance)
{
PropertyB = (ClassB)(ShimClassB)someInstance;
}
解决这个问题。我建议更改您的 ClassA 构造函数,以便输入它并且不接受 object,当您将 shimClassB 传递给此构造函数时,您会发现将使用用户定义的隐式转换:
// The user-defined implicit conversion takes care of this for us
ClassA(shimClassB);
public ClassA(ClassB someInstance)
{
PropertyB = someInstance;
}
或者如果你想保持你的构造函数原样:
ClassA((ClassB)shimClassB);
public ClassA(object someInstance)
{
PropertyB = (ClassB)someInstance;
}