Preom
Preom

Reputation: 1680

Why does creating an instance of a generic type work like this?

Use case:

class A {};

class B : A {};

class C : A {};

class Foo <T>: where T : A {
...

// T bar = new T(arg1, arg2);

...

}

class FooB: Foo<B> {...}

class FooC: Foo<C> {...}

I want to use children of class A in corresponding children of Foo. FooA and FooB have some extra logic that only works with A and B respectively. As a side note, I hope this is the right way to do this because I feel like this is a common scenario but I haven't seen any info on it elsewhere.


Shouldn't the compiler be able to see that based on the constraint that T has to be a child of A what constructor is appropriate? I am currently able to just add a new() constraint and then call methods on the newly created object. This was also done here in a similar question. What I don't understand is why the compiler can call methods on an unknown type but can't instantiate it. Especially with constraints that should allow it to do so.

For example, why can I do something like:

class Foo <T>: where T: A, new() {
...
T bar = new T()
bar.Construct(arg1, arg2);
...

Upvotes: 1

Views: 55

Answers (1)

Ofir Winegarten
Ofir Winegarten

Reputation: 9365

Let's examine the next classes:

public class A
{
    public int SomeInt { get; set; }

    public A(int someInt)
    {
        this.SomeInt = someInt;
    }
}

public class B : A
{
}

This will not compile since, there is not public default constructor on A and the compiler doesn't know how to initialize A from B. Constructors are not inherited in C#:
From Microsoft documentation:

Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

Surely, after we'll fix it, we can call on the SomeInt property from the B class. That's after all what inheritance is.

So, for your question - the compiler doesn't know which constructors will be defined for the T type at run-time. However it knows, since its a sub-class of A which method/properties it can access.

Upvotes: 2

Related Questions