Search code examples
c#classreturnradixderived

How to return the derived type from base method


For better understanding, here is what I would like to do:

Dog dog = Animal.Color("Red").Paw(4); 
Bird bird = Animal.Color("Blue").Wing(1);

With the below code I could do the following:

Dog dog = Animal.Paw(4).Color("Red"); 
Bird bird = Animal.Wing(1).Color("Blue");

But I would like to do it the first way.

Here is my code design so far:

public class Animal 
{
    public static string color = "";

    public Animal Color( string _color )
    {
        color = _color;

        return this.GetType() ;
    }
}

public class Dog : Animal 
{
    public static int pawNumber = 0;

    public static Dog Paw( int _pawNumber )
    {
        pawNumber = _pawNumber;

        return this;
    }
}

public class Bird : Animal 
{
    public static int wingNumber = 0;

    public Bird Wing( int _wingNumber )
    {
        wingNumber = _wingNumber;

        return this;
    }
}

So, basically, it's not working because Color is typed as Animal, even if I return this.GetType() ( which gives me the right type ) , the return value is not typed as needed.

Hope I was clear enough and that somebody can help me!


Solution

  • You can do this. It's really ugly but does what you ask.

    class Program
    {
        static void Main(string[] args)
        {
            Dog dog = new Dog().Color("Red").Paw(4);
            Bird bird = new Bird().Color("Blue").Wing(1);
        }
    }
    
    public abstract class Animal
    {
        private string color = "";
        public Animal Color(string _color)
        {
            color = _color;
            return this;
        }
    }
    
    public abstract class ChainingAnimal<T> : Animal
        where T : Animal
    {
        public T Color(string _color)
        {
            return (T)base.Color(_color);
        }
    }
    
    public class Dog : ChainingAnimal<Dog>
    {
        private int pawNumber = 0;
        public Dog Paw(int _pawNumber)
        {
            pawNumber = _pawNumber;
            return this;
        }
    }
    
    public class Bird : ChainingAnimal<Bird>
    {
        private int wingNumber = 0;
        public Bird Wing(int _wingNumber)
        {
            wingNumber = _wingNumber;
            return this;
        }
    }