Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add type parameter constraint to prevent abstract classes

Tags:

c#

Is it possible to restrict a type parameter to concrete implementations of an abstract class, if those implementations don't have default constructors?

For example, if I have:

public abstract class Animal
{
    private Animal()
    {
    }

    public Animal(string name)
    {
        // ...
    }

  // ...
}


public class Penguin : Animal
{
    // ...
}


public class Chimpanzee : Animal
{
    // ...
}

And I also have the following class:

public class ZooPen<T>
   where T : Animal
{
    // ...
}

I would like to allow new ZooPen<Penguin>() and new ZooPen<Chimpanzee>(), but I would like to disallow new ZooPen<Animal>().

Is this possible?

like image 639
Andrew Keller Avatar asked May 28 '13 15:05

Andrew Keller


2 Answers

You can add the new() constraint, which will require that the class not be abstract and have a default constructor.

like image 94
SLaks Avatar answered Oct 23 '22 22:10

SLaks


Here is one way to accomplish what you're asking for.

abstract class Animal
{
    readonly string Name;
    Animal() { }
    public Animal(string name) { Name = name; }
}

abstract class Animal<T> : Animal where T : Animal<T>
{
    public Animal(string name) : base(name) { }
}

class Penguin : Animal<Penguin>
{
    public Penguin() : base("Penguin") { }
}

class Chimpanzee : Animal<Chimpanzee>
{
    public Chimpanzee() : base("Chimpanzee") { }
}

class ZooPen<T> where T : Animal<T>
{
}

class Example
{
    void Usage()
    {
        var penguins = new ZooPen<Penguin>();
        var chimps = new ZooPen<Chimpanzee>();
        //this line will not compile
        //var animals = new ZooPen<Animal>();
    }
}

Anyone maintaining this code will probably be a bit confused, but it does exactly what you want.

like image 27
dss539 Avatar answered Oct 23 '22 21:10

dss539