C# 为什么创建泛型类型的实例会像这样工作?

C# 为什么创建泛型类型的实例会像这样工作?,c#,generics,C#,Generics,用例: 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> {...} 让我们检查下一个类: public class A { public int SomeInt { get

用例:

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> {...}

让我们检查下一个类:

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

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

public class B : A
{
}
这将不会编译,因为
A
上没有公共默认构造函数,并且编译器不知道如何从
B
初始化
A
。 构造函数不是在C#中继承的:
来自Microsoft:

与其他成员不同,实例构造函数不是继承的,并且类除了在类中实际声明的实例构造函数之外,没有其他实例构造函数。如果没有为类提供实例构造函数,则会自动提供一个没有参数的空构造函数

当然,在修复它之后,我们可以从
B
类调用
SomeInt
属性。这毕竟是继承


因此,对于您的问题,编译器不知道在运行时将为
t
类型定义哪些构造函数。然而,它知道,因为它是
a
的一个子类,它可以访问哪些方法/属性。

不幸的是,编译器不够聪明,无法确定需要调用什么构造函数,您需要知道方法是在接口中实现的。所以当你说
为什么编译器可以调用未知类型的方法时
是错误的。因为类型不是未知的。接口和类都有约束。所以编译器可以对泛型类型调用方法并不奇怪。
public class A
{
    public int SomeInt { get; set; }

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

public class B : A
{
}