覆盖非虚拟字符串属性

时间:2017-03-10 17:01:52

标签: c# asp.net .net

我正在尝试对属性非虚拟的方法进行单元测试,并且有两层继承 - 因此我无法创建模拟。我创建了一个假的,但由于某种原因,属性值仍然是空的。

public class Cart {
    public string Currency { get; set; } // I'm trying to override this
}

// My fake class
public class CartFake : Cart
{
    public new string Currency {  // This should hide SomeBaseBase.Cart.Currency - but it does not
        get { return "USD"; }
        set { value = "USD"; }
    }
}


public abstract class SomeBaseBase {
    public virtual Cart Cart { get; set; }
}

public class Base : SomeBaseBase {
   public string OtherProperties { get; set; }
}

// class under test
public class SomeClassFake : Base {
    public override Cart Cart => new CartFake();


    // Then when test is running I have this
    var currency = Cart.Currency // returns "" - when debugging I see two "Currency" properties and currency gets populated with ""
}

由于某些原因,当测试运行时,我看到两个货币属性,而var currency =得到货币“”而不是“USD”

为什么?我怎样才能让美元被填充?

编辑:

public class CartFake : Cart
{
    public CartFake() : base()
    {
        Currency = "USD";
    }
}

由于某种原因,行:Cart.Currency仍然是空的:(

2 个答案:

答案 0 :(得分:1)

这是阴影或隐藏的工作方式,即(使用new关键字与类成员),如果您希望将派生类(CartFake)引用为基类(Cart )会让你访问派生类(CartFake)的属性值,你错了。

如果您在基类(virtual)中定义了Cart属性并且在派生类(override中使用CartFake关键字覆盖了它,那么就会发生这种情况,但事实并非如此。

对于您期望的行为,您的代码需要如下:

public class Cart {
    public virtual string Currency { get; set; } // I'm trying to override this
}

// My fake class
public class CartFake : Cart
{
    public override string Currency {  // This should hide SomeBaseBase.Cart.Currency - but it does not
        get { return "USD"; }
        set { value = "USD"; }
    }
}

现在当您使用类型基类的变量访问属性Currency但对象实际上是Derived类类型时,您将返回 USD

当您使用类型Currency的引用访问Cart属性时,它隐藏了Currency中定义的属性CartFake

如果您希望CartFake获得 USD ,则需要将其强制转换回Currency

// class under test
public class SomeClassFake : Base {
    public override Cart cart => new CartFake();


    // Then when test is running I have this
    var cartFake = cart as CartFake;
    var currency = cartFake.Currency // will return USD 
}

为了更清晰,请参阅问题Difference between Shadowing and Overriding

答案 1 :(得分:0)

您需要将Cart投射到您要返回的属性的CartFake对象

var currency = ((CartFake)Cart).Currency;