C# 如何将垫片铸造为混凝土类型?
我有一个基于ClassA.PropertyB的垫片,其中PropertyB是ClassB类型。ClassA是内部的,位于测试项目中的另一个程序集中。我在AssemblyInfo.cs中添加了一个引用,这样我的测试项目就可以看到这个内部文件,并且我能够创建垫片 我想通过构造函数将shimClassB实例发送到ClassA中:C# 如何将垫片铸造为混凝土类型?,c#,.net,unit-testing,microsoft-fakes,C#,.net,Unit Testing,Microsoft Fakes,我有一个基于ClassA.PropertyB的垫片,其中PropertyB是ClassB类型。ClassA是内部的,位于测试项目中的另一个程序集中。我在AssemblyInfo.cs中添加了一个引用,这样我的测试项目就可以看到这个内部文件,并且我能够创建垫片 我想通过构造函数将shimClassB实例发送到ClassA中: public ClassA(object someInstance) { PropertyB = (ClassB)someInstance; } public Cla
public ClassA(object someInstance)
{
PropertyB = (ClassB)someInstance;
}
public ClassA(object someInstance)
{
PropertyB = (ClassB)(ShimClassB)someInstance;
}
上面抛出一个InvalidCastException:
Unable to cast object of type shimClassB to type ClassB.
是否有其他技术可以将shim实例放入ClassA?我认为这样做没有任何问题。请验证属性的类型是否正确,或者尝试将某些ShimClassB对象分配给ClassB类型的新变量
向我们展示您的代码可能会有所帮助,尽管我只是尝试了完全相同的示例,没有得到任何异常。需要注意的是,
ClassB
和ShimClassB
没有基类派生的类关系。所以你正在做的演员可能并没有达到你的预期。由于Microsoft.Fakes为您提供了用户定义的转换,您看到隐式转换正在工作
您的ShimClassB
继承自ShimBase
,其中T是ClassB
。此类有一个方法,该方法在ShimClassB
和ClassB
之间引入用户定义的隐式转换
public static implicit operator T(ShimBase<T> shim)
您不能强制转换到ClassB
,因为在对象
和ClassB
之间没有定义转换
public static implicit operator T(ShimBase<T> shim)
根据C#编程语言规范6.2.4显式引用转换:
要使显式引用转换在运行时成功,值
源操作数的类型必须为null,或对象的实际类型
源操作数引用的类型必须是可以转换的类型
通过隐式引用转换(第6.1.6节)转换为目标类型
或装箱转换(§6.1.7)。如果需要显式引用转换
失败,将引发System.InvalidCastException
您会发现,如果代码具有中间强制转换,它将不再抛出InvalidCastException
,但是这不是最终解决方案,因为您不希望对构造函数中的垫片进行强制转换:
public ClassA(object someInstance)
{
PropertyB = (ClassB)someInstance;
}
public ClassA(object someInstance)
{
PropertyB = (ClassB)(ShimClassB)someInstance;
}
解决这个问题。我建议更改ClassA构造函数,使其类型化且不接受对象
,当您将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;
}