Prevent instantiating derived class from anywhere except based class in C#

public abstract class Vehicle
{
    public static GetVehicle()
    {
        if (Context.IsMountain())
        {
            return new Truck();
        }
        else
        {
            return new Car();
        }
    }
}
public class Car : Vehicle
{
    // Prevent creating Car directly
    private Car() { }
}
public class Truck : Vehicle
{
    // Prevent creating Truck directly
    private Truck() { }
}

With the above code, C# cannot compile because the base class can't access the derived-class constructor. Is there a different way to accomplish this? Basically, I want to prevent instantiating derived-class publicly.

Jon Skeet
people
quotationmark

The simplest approach is probably to make your implementations private classes inside the base class:

public abstract class Vehicle
{
    public static Vehicle GetVehicle()
    {
        if (Context.IsMountain())
        {
            return new Truck();
        }
        else
        {
            return new Car();
        }
    }

    private class Car : Vehicle {}
    private class Truck : Vehicle {}
}

That will prevent clients from using any Car-specific members, of course - but in many cases that's fine.

An alternative is to just make them internal classes, if you don't mind other code within the same assembly accessing the subclasses. This is an approach I use in Noda Time, for example - I have multiple CalendarSystem subclasses, but the clients (outside the assembly) only know about the factory methods/properties within CalendarSystem itself.

people

See more on this question at Stackoverflow