0

Just curious if there is a solution for this without making the base class method virtual and the derived method marked 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. 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.

2
  • 1
    Why not just use virtual ? that is kinda the easiest and most obvious way to do this. Commented Jul 22, 2012 at 19:34
  • cause I just wanted to know why the new keyword wouldn't work, Jon cleared it up. I hardly ever use inheritance, prefer interfaces, DI and composition Commented Jul 22, 2012 at 19:50

2 Answers 2

4

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.

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. Foo2.DoSomething is not an implementation of 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. 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.

Sign up to request clarification or add additional context in comments.

2 Comments

As always, thanks Jon. Yes, Composition is a much better option, this was kind of a try and see thing, before I tried just using a wrapper class around the base (composition). Was just curious why it wasn't working this cleared it up!
Oh well, I love the taste of a new lesson at sunday. Congrats, Jon
1

Try changing your Foo2 declaration like this:

public class Foo2 : Foo, IFoo 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.