Search code examples
c#oopinheritancevirtual

How to call derived class virtual method?


I created these classes:

public abstract class Node
{
    public virtual NodeModel CreateModel()
    {
        throw new NotImplementedException();
    }
}

public class Folder : Node
{
    public virtual FolderModel CreateModel()
    {
        // Implementation
    }
}

public class Item : Node
{
    public virtual ItemModel CreateModel()
    {
        // Implementation
    }
}

Then in my program I have a List of Node which only contains Item and Folder objects. When I loop on the list and try to call the CreateModel() method, this is always the Node class method which is called (therefore throwing the exception).

I cannot change CreateModel() to abstract as the return type is different depending on the derived type. I was wondering if it is possible to have a different return type. I also want to avoid generics. The fact is that Intellisense is showing me the upper class method when playing around with an instance of it. If I remove the virtual implementation from the upper class, then it displays the base class implementation. This is where I thought it is actually possible.

So how can I force the program to call the upper class method?


EDIT: The answer was actually simple and was right under my nose. The return type does not matter as it will inherits from the return type defined in the base class abstract CreateModel(). I just marked the method as abstract in my base class and it works just fine. I don't know why I got confused at some moments because now it seems pretty obvious to me.

Thanks everybody for helping me out.


Solution

  • C# does not support covariance in function return types.

    Anyway, you only need to specify the return type of CreateModel() as something else than NodeModel when other parts are relying on them to be more specific, e.g. when FolderModel extends NodeModel with more methods.

    If you are only iterating over a list of Node objects and call CreateModel() it is not needed, just declare Folder.CreateModel() with NodeModel return type, even though it returns a FolderModel.