2

Consider the following -

void Main()
{
    var c = new C();
    c.Print();
}

public abstract class A
{
    public virtual void Print()
    {
        Console.WriteLine("I'm in A!");
    }
}

public abstract class B : A
{
    public abstract override void Print();
}

public class C : B
{
    public override void Print()
    {
        Console.WriteLine("I'm in C!");

        base.Print();
    }
}

This, of course, won't compile, as it thinks I am trying to invoke B's print method, which is abstract. What I want to do is call C's print method, and then have it call the base's print method, which would "chain" back to A's print method. I would like the output to be -

I'm in C!
I'm in A!

Is doing this even possible? What am I doing wrong?

EDIT: I'd like to add that the main point about the code above is that I'm trying to force anyone that extends B to implement their own Print method.

Paul McLean
  • 3,450
  • 6
  • 26
  • 36
  • Use it public c { public C():base(){} Print(); } – user1956570 Oct 04 '13 at 04:18
  • It just seems like the hierarchy is fragile and should be redesigned. You need to consider whether inheritance is appropriate here. – ChaosPandion Oct 04 '13 at 04:18
  • Why are you trying to force the developer of C to copy and paste the code from A into C? – jmoreno Oct 04 '13 at 04:54
  • @jmoreno: Sorry, I don't quite follow. How am I forcing them to do that? – Paul McLean Oct 04 '13 at 04:57
  • If they wanted a different result, they would have overridden it on their own. Since they want the exact same result as A, the best way of doing that is to use the code from A. You are preventing them from doing it one way, so they have to do it another way. – jmoreno Oct 04 '13 at 05:07

3 Answers3

2

Well, you could do

public abstract class A
{
    public virtual void Print()
    {
        Console.WriteLine("I'm in A!");
    }
}

public abstract class B : A
{
    public override void Print()
    {
        base.Print();
    }
}

public class C : B
{
    public override void Print()
    {
        Console.WriteLine("I'm in C!");

        base.Print();
    }
}

Which is effectively

public abstract class A
{
    public virtual void Print()
    {
        Console.WriteLine("I'm in A!");
    }
}

public abstract class B : A
{
}

public class C : B
{
    public override void Print()
    {
        Console.WriteLine("I'm in C!");

        base.Print();
    }
}
Adriaan Stander
  • 162,879
  • 31
  • 289
  • 284
  • This is the best answer I could think of too, but it loses the one element I would like to have, which is forcing classes that extend B to implement their own Print(). – Paul McLean Oct 04 '13 at 04:23
  • Unless B has diffefrent logic, other implementations that you are not showing us, why are you wrapping A? – Adriaan Stander Oct 04 '13 at 04:28
  • To add more background info, most of my implementations (say, class D, E and F) extend A directly. In those cases, implementing Print() is optional. However, if B is used to extend A, I don't want implementing Print to be optional, I want it to be mandatory (and I also want it to be done in yet another layer of extension) – Paul McLean Oct 04 '13 at 04:34
1

If you remove the attempt to override from B:

public abstract override void Print();

That is exactly what it will do.

Full Code:

    static void Main(string[] args)
    {
        var c = new C();
        c.Print();

        Console.ReadLine();
    }

    public abstract class A
    {
        public virtual void Print()
        {
            Console.WriteLine("I'm in A!");
        }
    }

    public abstract class B : A
    {
    }

    public class C : B
    {
        public override void Print()
        {
            Console.WriteLine("I'm in C!");
            base.Print();
        }
    }

Result:

I'm in C!
I'm in A!
Khan
  • 17,904
  • 5
  • 47
  • 59
1

There is no way you can force a class to provide it's own implementation, after all it could just call base.Print() or even just provide an empty method implementation.

For a similar discussion see: How to force overriding a method in a descendant, without having an abstract base class?

Community
  • 1
  • 1
codemonkeh
  • 2,054
  • 1
  • 20
  • 36