C# 如何将垫片铸造为混凝土类型?

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

我有一个基于ClassA.PropertyB的垫片,其中PropertyB是ClassB类型。ClassA是内部的,位于测试项目中的另一个程序集中。我在AssemblyInfo.cs中添加了一个引用,这样我的测试项目就可以看到这个内部文件,并且我能够创建垫片

我想通过构造函数将shimClassB实例发送到ClassA中:

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;
}