【问题标题】:How to cast shim as concrete type?如何将垫片铸造成混凝土类型?
【发布时间】:2014-03-07 21:42:32
【问题描述】:

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

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

public ClassA(object someInstance)
{
  PropertyB = (ClassB)someInstance;
} 

上面抛出了一个 InvalidCastException:

Unable to cast object of type shimClassB to type ClassB.

是否有其他技术可以让 shim 实例进入 ClassA?

【问题讨论】:

    标签: c# .net unit-testing microsoft-fakes


    【解决方案1】:

    需要注意的是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;
    } 
    

    【讨论】:

      【解决方案2】:

      我认为这样做没有任何问题。请验证您的属性的类型是否正确,或尝试将某个 ShimClassB 对象分配给 ClassB 类型的新变量。

      向我们展示您的代码可能会有所帮助,即使我只是尝试了完全相同的示例而没有出现任何异常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-09
        • 1970-01-01
        • 2011-05-19
        • 2019-07-21
        相关资源
        最近更新 更多