覆盖非虚拟字符串属性 [英] Override non-virtual string property
问题描述
我正在尝试对属性为非虚拟且有两层继承的方法进行单元测试-因此,我无法创建模拟.我创建了一个伪造品,但是由于某种原因,该属性值仍然为空.
I'm trying to unit test a method where a property is non-virtual, and there are two layers of inheritance - therefore I can not create a mock. I've created a fake, however for some reason the property value is still empty.
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 ""
}
由于某种原因,在测试运行时,我看到两个Currency属性,并且var currency =获取货币"而不是"USD"
For some reason when the test is running I see two Currency properties and var currency = gets currency "" instead of "USD"
那是为什么?如何使USD填充?
why is that? how can I make it so that USD is populated?
public class CartFake : Cart
{
public CartFake() : base()
{
Currency = "USD";
}
}
出于某些原因:Cart.Currency仍然为空:(
For some reason line: Cart.Currency is still empty :(
推荐答案
如果您希望持有派生类,则这就是阴影或隐藏的工作方式,即(将 new
关键字与类成员一起使用)( CartFake
)作为基类( Cart
)的引用将使您可以访问派生类( CartFake
)的属性值,这是错误的
This is how shadowing or hiding works i.e. (using new
keyword with members of class), if you are expecting that holding derived class (CartFake
) reference as base class (Cart
) would give you access to the value of property of derived class (CartFake
), you are wrong.
如果您在基类( Cart
)中具有定义为 virtual
的属性,并且在其中使用 override
关键字覆盖了该属性,则将发生这种情况.派生类( CartFake
),但事实并非如此.
That would have happened if you had the property defined virtual
in base class (Cart
) and you had overriden it using override
keyword in derived class (CartFake
), but that is not the case.
对于您期望的行为,您的代码需要像这样:
For the behavior that you are expecting for that your code needs to be like:
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 .
now when you access the property Currency
using variable of type base class but object is actually of type Derived class, you will get USD back.
使用类型为 Cart
的引用访问 Currency
属性时,它将隐藏在 CartFake <中定义的属性
Currency
./code>.
When you are accessing the Currency
property using reference of type Cart
it is hiding the property Currency
defined in the CartFake
.
如果您要由于 Currency
的结果而获得 USD ,则需要将其退回 CartFake
,例如:
You need to cast it back to CartFake
, if you want to get USD as result of Currency
like:
// 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
}
有关更多信息,请参见问题阴影与覆盖之间的差异清晰.
Refer to the question Difference between Shadowing and Overriding for more clarity.
这篇关于覆盖非虚拟字符串属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!