Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Polymorphism and Method Inheritance

Consider the following classes:

public class X {};
public class Y : X {};
public class Z : X {};

public class A {
    public bool foo (X bar) { 
        return false;
    }
};

public class B : A { 
    public bool foo (Y bar) { 
       return true;
    }
};    

public class C : A { 
    public bool foo (Z bar) { 
       return true;
    }
};

Is there a way to achieve the following desired output?

A obj1 = new B();
A obj2 = new C();

obj1.foo(new Y()); // This should run class B's implementation and return true
obj1.foo(new Z()); // This should default to class A's implementation and return false

obj2.foo(new Y()); // This should default to class A's implementation and return false
obj2.foo(new Z()); // This should run class C's implementation and return true

The issue I am having is that class A's implementation is always being called regardless of the arguments passed.

like image 810
Dan Brenner Avatar asked Feb 10 '23 02:02

Dan Brenner


2 Answers

You need to make the foo method in class A virtual so it can be overridden properly and called polymorphically.

public class A { public virtual bool Foo (X bar) { ... } }
public class B { public override bool Foo (X bar) { ... } }

The way you are doing it at the moment, is effectively defining a new method implementation in B and C which will only be called if the instance is of that type. Since you are declaring them as type A (A obj1 = new B();) and the method is not virtual then the A implementation will always be called.

like image 131
Trevor Pilley Avatar answered Feb 13 '23 02:02

Trevor Pilley


I believe you desire to define virtual method and override it with a signature that contains derived types. That is not possible as the method that overrides the base one should have the same signature. Probably this is because that would require the compiler to apply complex traversal rules. So as suggested in the previous answer to get the desired behavior:

public class A { public virtual bool Foo (X bar) { ... } }
public class B { 
    public override bool Foo (X bar) {
         if(bar is Y) { ... } 
         else base.Foo(bar);
    }
}
like image 37
Artyom Avatar answered Feb 13 '23 02:02

Artyom