1

I have simplified my true issue into the following example:

namespace Cars    
{    
    public class Program    
    {    
        public static void Main(string[] args)    
        {    
            Car car1 = Car.Create(new Driver(1, "A", License.Private));    
            Car car2 = Car.Create(new Driver(2, "B", License.Truck));    
            Car car3 = Car.Create(new Driver(3, "C", License.Bus));        

            car1.OpenTrunk();    
            car2.AttachWagon();    
            car3.OpenBackDoor();    
        }    
    }     

    enum License { Private, Truck, Bus } 

    public class Driver    
    {    
        public uint ID { get; private set; }    
        public string Name { get; private set; }    
        public License License { get; private set; }

        public Driver(uint id, string name, License license)    
        {    
            ID = id;    
            Name = name;    
            License = license;    
        }    
    }        

    public abstract class Car    
    {    
        protected Driver driver;        

        public Car(Driver driver)    
        {    
            this.driver = driver;    
        }    

        public static Car Create(Driver driver)    
        {    
            switch (driver.License)    
            {    
                License.Private: return new Private(driver);    
                License.Truck: return new Truck(driver);    
                License.Bus: return new Bus(driver);    
            }    
        }    
    }   

    public class Private : Car   
    {    
        public Private(Driver driver) : base(driver) {}

        public void OpenTrunk();
    }     

    public class Truck : Car    
    {    
        public Truck(Driver driver) : base(driver) {}

        public void AttachWagon();    
    }        

    public class Bus : Car    
    {    
        public Bus(Driver driver) : base(driver) {}

        public void OpenBackDoor();    
    }    
}

Let's say I have a parent class Car from which three classes derives: Private, Truck and Bus.

The constructor of the derived classes receive one parameter of class Driver.

The class Driver contain among other properties the property License.

Assuming that each driver can have a license only to one of the three types of cars (Private, Truck, Bus).

I want to create a function which will return me an object of one of the derived classes based on the Driver provided to the function.

I want the user of this function to receive an object on which he may call specific functions for each derived class such as bus1.OpenBackDoor() or truck1.AttachWagon().

What will be the best way to do so while keeping the general structure of the example code (the Create method may be called differently) ?

LEyahoo
  • 83
  • 1
  • 9
  • 3
    You're looking to implement a factory pattern: https://www.c-sharpcorner.com/article/factory-method-design-pattern-in-c-sharp/ This pattern is used to create instances of a type, usually related types, and you can give it a parameter (the driver). The problem here is, if the functions are different, defining it as a common base class cannot provide that functionality. You need to use a common interface. If you don't know in advance which type it will be or inherit from, you can't know what members it has either. – Glenn van Acker Dec 04 '19 at 10:56
  • 1
    @LEyahoo You can create a generic method to handle that (specific car functions at least), but need to update your classes a little bit. Do you need an object, based on `Driver` properties or can specify the generic argument to get a car instance – Pavel Anikhouski Dec 04 '19 at 11:34
  • @Pavel Anikhouski, I need information which is kept in the `Driver` object to know which of the derived class's c'tor to use. – LEyahoo Dec 04 '19 at 13:22
  • @LEyahoo Than you should use the factory pattern, as comment above says, return the `Car` instance (or common interface) and check that you call the specific method. Because for generic type you have to explicitly define the required type and compile time, something like `var car1 = Car.Create(new Driver(..)); car1.OpenTrunk();` – Pavel Anikhouski Dec 04 '19 at 14:17
  • @Pavel Anikhouski, thanks. If I'll create a static method in the parent `Car` class which will retrive the desired derived class type, is there an option to provide it to the generic `Create<>` method inside the <> brackets? It is not an elegant way but it will release the user of thouse classes from casting the returned object in order to use specific derived class methods. – LEyahoo Dec 05 '19 at 08:14

0 Answers0