[英]Derived class new method should override but isn't
Just curious if there is a solution for this without making the base class method virtual and the derived method marked override: 只是想知道是否有解决方案而不将基类方法设为虚拟并且派生方法标记为override:
I want it to jump into the derived method, set the property to true (for testing purposes, almost like this is a mock), but it's jumping into the base class. 我希望它跳到派生方法中,将属性设置为true(出于测试目的,几乎就像是一个模拟),但是它跳到了基类中。 The only solution is to make the base virtual, I thought I could mark it new in the derived and that would work.
唯一的解决方案是将基础虚拟化,我想我可以在派生数据库中将其标记为新的,并且可以使用。
public class SomeClass
{
private readonly IFoo _foo;
public SomeClass(IFoo foo)
{
_foo = foo;
}
public void DoSomething()
{
_foo.DoFoo();
}
}
public interface IFoo
{
void DoFoo();
}
public class Foo : IFoo
{
public void DoFoo()
{
}
}
public class Foo2 : Foo
{
public bool DoFooWasCalled { get; set; }
public new void DoFoo()
{
DoFooWasCalled = true;
base.DoFoo();
}
}
Here's the test that is failing: 这是失败的测试:
[TestFixture]
public class TestingCSInheritance
{
[Test]
public void TestMethod()
{
var foo = new Foo2();
var someClass = new SomeClass(foo);
someClass.DoSomething();
foo.DoFooWasCalled.ShouldBe(true);
}
}
My guess is that because I'm using dependency injection with an interface it's using the base class, but I'm not sure why. 我的猜测是,因为我在接口上使用依赖项注入,所以它在使用基类,但是我不确定为什么。
The only solution is to make the base virtual, I thought I could mark it new in the derived and that would work.
唯一的解决方案是将基础虚拟化,我想我可以在派生数据库中将其标记为新的,并且可以使用。
No. If you create a new method, only code which knows about the expression with a compile-time type of Foo2
will call Foo2.DoSomething
. 否。如果您创建一个新方法,则只有知道编译时类型为
Foo2
的表达式的Foo2
才能调用Foo2.DoSomething
。
Even though TestMethod
knows about foo
as a Foo2
, SomeClass.DoSomething
only knows about it as IFoo
, so it's just using the IFoo
implementation. 即使
TestMethod
知道foo
作为Foo2
, SomeClass.DoSomething
只知道它为IFoo
,因此它只是使用IFoo
实现。 Foo2.DoSomething
is not an implementation of IFoo
. Foo2.DoSomething
不是 IFoo
的实现。
You want polymorphism, but you've effectively discarded it by not using a virtual method. 您想要多态性,但是您已经通过不使用虚拟方法有效地将其丢弃。
The only other option is to reimplement IFoo
in Foo2, which is the solution described by Sergey. 唯一的其他选择是在Foo2中重新实现
IFoo
,这是Sergey描述的解决方案。 Note that this ends up with some pretty confusing code. 请注意,这最终会产生一些令人困惑的代码。 Method hiding of any kind almost always does.
任何类型的方法隐藏几乎总是如此。 Fundamentally, if you want the effect of a virtual method, you should use a virtual method...
从根本上讲,如果要使用虚拟方法的效果,则应使用虚拟方法...
Alternatively, it would be cleaner if you used composition instead of inheritance: 另外,如果您使用组合而不是继承,那会更干净:
public class MockFoo : IFoo
{
private readonly Foo foo = new Foo();
private bool doSomethingWasCalled;
public void DoSomething()
{
doSomethingWasCalled = true;
foo.DoSomething();
}
}
This delegates the call to DoSomething
instead of trying to juggle an inheritance hierarchy. 这
DoSomething
调用委派给DoSomething
而不是尝试处理继承层次结构。
尝试像这样更改Foo2
声明:
public class Foo2 : Foo, IFoo
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.