Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding method to change return type

Tags:

c#

I have a situation in which I want to override a method of the base class in order to slightly change the return type of the method. By slightly change I mean return an object that inherits from the object that would have been returned by the method in the base type ... actually, a little code would make this easier ...

class Program
{
    static void Main(string[] args)
    {
        var obj = new ParentClass();
        Console.WriteLine("Parent says: " + obj.ShowYourHand());

        var obj2 = new ChildClass();
        Console.WriteLine("Child says: " + obj2.ShowYourHand());

        Console.ReadLine();
    }
}

public class ParentClass
{
    public string ShowYourHand()
    {
        var obj = GetExternalObject();
        return obj.ToString();
    }
    protected virtual ExternalObject GetExternalObject()
    {
        return new ExternalObject();
    }
}

public class ChildClass : ParentClass
{
    protected virtual new ExternalObjectStub GetExternalObject()
    {
        return new ExternalObjectStub();
    }
}

public class ExternalObject
{
    public override string ToString()
    {
        return "ExternalObject";
    }
}

public class ExternalObjectStub : ExternalObject
{
    public override string ToString()
    {
        return "ExternalObjectStub";
    }
}

The issue I have is that the instance of obj2 doesn't call it's version of GetExternalObject() but rather uses it's parent's implementation.

I think that it is doing so because in the code

var obj = GetExternalObject();

the type of obj is expected to be ExternalObject in the parent class. I understood however that C# cannot distinguish between methods based on return type.

I know there are other solutions to the issue such as defining an IExternalObject so don't get too hung up about that. All I wanted to know was what the thinking is that prevents the child classes GetExternalObject from being called even by the child class itself?

Or am I doing something totally daft? :-)

like image 447
devprog Avatar asked Sep 02 '11 11:09

devprog


1 Answers

Or am I doing something totally daft? :-)

Yes, you are. You can't change the return type of a method by overriding it. I don't understand it in your sample anyway. Just leave the return type as it was and return a new ExternalObjectStub. This works, because ExternalObjectStub derives from ExternalObject.

Changing the return type by hiding the base member with new as you do it, is generally a very bad idea, because it leads to a class that can't be used in a polymorphic way. This is exactly what you are experiencing here: If the type of the variable that holds the reference is of type ParentClass it calls the method in ParentClass, even if the instance really is of type ChildClass, because ChildClass doesn't provide an overriden implementation of GetExternalObject.

like image 106
Daniel Hilgarth Avatar answered Oct 10 '22 02:10

Daniel Hilgarth