Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

base.Method() with multiple levels of inheritance not being called?

I've searched and not been able to find any solution to my problem. My scenario is very simple:

public class A
{
    public virtual void MethodOne()
    {
       Console.log( "A" ); 
    }
}

public class B : A
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.log( "B" );
    }
}

public class C : B
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.log( "C" );
    }
}

What I am trying to do is have an instance of class C (we'll name it 'instanceC') call both the overridden method of its parent, and its grandparent. So I'd expect this:

instanceC.MethodOne();
// Output:
// "A"
// "B"
// "C"

But instead am getting this:

instanceC.MethodOne();
// Output
// "A"
// "C"

with class B's method being skipped over. Is this not possible? I thought this is the whole point of inheritance/polymorphism. Thanks in advance!

like image 428
helios Avatar asked May 04 '13 17:05

helios


People also ask

How do you call a base class method in C#?

base (C# Reference)The base keyword is used to access members of the base class from within a derived class: Call a method on the base class that has been overridden by another method. Specify which base-class constructor should be called when creating instances of the derived class.

Is multiple inheritance allowed in Python?

Yes, Python supports multiple inheritance. Like C++, a class can be derived from more than one base classes in Python. This is called Multiple Inheritance.

Why .NET do not support multiple inheritance?

NET and Java designers did not allow multiple inheritance because they reasoned that adding MI added too much complexity to the languages while providing too little benefit. For a more fun and in-depth read, there are some articles available on the web with interviews of some of the language designers.

Can you inherit from multiple base classes in C#?

But C# does not support multiple class inheritance. To overcome this problem we use interfaces to achieve multiple class inheritance. With the help of the interface, class C( as shown in the above diagram) can get the features of class A and B.


2 Answers

Your example works as expected for me. I see A B C. I think your most likely issue is that C doesn't extend B. However, let me suggest an arguably safer pattern while we're on the subject. You seem to want all overrides of MethodOne to execute code from their base classes. Great, inheritance is a good pattern for this. However, with this pattern you cannot force inheritors to execute the base logic because you cannot force them to call base.MethodOne(). Even if they do callbase.MethodOne(), you cannot ensure the order of the logic. Will they call base.MethodOne() at the beginning of the method, middle of the method, or end of the method? Often, in these types of patterns you want sub classes to execute all the base logic at the beginning of the function. The following pattern forces inheritors to execute base logic in the order base classes expect. It's technically less flexible but safer because inheritors must extend the base classes in a way that the base classes specify.

public class A
{
    //Don't make this method virtual because you don't actually want inheritors 
    //to be able to override this functionality.  Instead, you want inheritors
    //to be able to append to this functionality.
    public void MethodOne()
    {
        Console.WriteLine( "A" ); 
        MethodToBeOverriddenOne();
    }
    //Expose a place where inheritors can add extra functionality
    protected virtual void MethodToBeOverriddenOne() { }      
}

public class B : A
{
    //Seal the method because you don't actually want inheritors 
    //to be able to override this functionality.  Instead, you want inheritors
    //to be able to append to this functionality.
    protected sealed override void MethodToBeOverriddenOne()
    {
        Console.WriteLine("B");
        MethodToBeOverriddenTwo();
    }
    //Expose a place where inheritors can add extra functionality
    protected virtual void MethodToBeOverriddenTwo() { }  
}

public class C : B
{
    protected sealed override void MethodToBeOverriddenTwo()
    {
        Console.WriteLine("C");
    }
}
like image 107
Steven Wexler Avatar answered Sep 28 '22 01:09

Steven Wexler


The example you posted works perfectly, whatever you are doing in your actual code is different than what you posted.

Here is your code running on ideone working as exactly like you wanted.

using System;

public class Test
{
        public static void Main()
        {
                var c = new C();
                c.MethodOne();
        }
}

public class A
{
    public virtual void MethodOne()
    {
       Console.WriteLine( "A" ); 
    }
}

public class B : A
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.WriteLine( "B" );
    }
}

public class C : B
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.WriteLine( "C" );
    }
}
like image 25
Scott Chamberlain Avatar answered Sep 28 '22 01:09

Scott Chamberlain