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?
Alas you have to explicitly give the type
DoSomething<Derived>(d2);
theoretically is not possible to create something that is abstract
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With