Richard Ev
Richard Ev

Reputation: 54097

Generic type constraint of new() and an abstract base class

Here we have a simple class herarchy, and use of generics with a type constraint of new()

public abstract class Base 
{
}

public class Derived : Base
{
}

public class TestClass
{
    private void DoSomething<T>(T arg) where T : new()
    {
    }

    public void TestMethod()
    {
        Derived d1 = new Derived();
        DoSomething(d1); // compiles

        Base d2 = new Derived();
        DoSomething(d2); // compile error
    }
}

The code fails to compile at the indicated line, with an error of:

'Base' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'Foo.DoSomething(T)'

This error is clear and makes sense, but I had hoped that the compiler would understand that all derivations of Base (that could be instantiated at this point) do have a public parameterless constructor.

Would this be theoretically possible for the compiler?

Upvotes: 10

Views: 5165

Answers (2)

lordkain
lordkain

Reputation: 3109

Alas you have to explicitly give the type

DoSomething<Derived>(d2);

theoretically is not possible to create something that is abstract

Upvotes: 8

Ryszard Dżegan
Ryszard Dżegan

Reputation: 25414

new Constraint (C# Reference):

To use the new constraint, the type cannot be abstract.

Calling:

Base d2 = new Derived();
DoSomething(d2);

You are in fact doing:

Base d2 = new Derived();
DoSomething<Base>(d2);

Since the Base is abstract, compilation error occurs.

So, you have to cast explicitly:

Base d2 = new Derived();
DoSomething((Derived) d2);

How could you ensure the compiler, that anyone ever put there something, that is not abstract?

The only manner that I see would be, if we got a keyword like "must-inherit-to-non-astract" and then create public must-inherit-to-non-abstract abstract class Base. After that, the compiler could be sure, that if you put the base instance into your method, that will be in fact a subclass, that is non-abstract and therefore can be instantiated.

Upvotes: 2

Related Questions