为什么我不能在 Generic<T> 方法中返回 T?

Dav*_*len 2 c# generics

以下代码表示我无法返回 Certification 类型的对象?为什么不按照 T 的定义呢?

public T BuildList<T>(T list, AttributeModel model) where T : Certification
{
    return new Certification("", "", "");
}
Run Code Online (Sandbox Code Playgroud)

更新:

我被要求解释为什么我认为这应该有效。公平的问题。

我读到“where T : Certification”意味着该方法也可以读作:

public Certification BuildList(Certification list, AttributeModel model)
Run Code Online (Sandbox Code Playgroud)

因此,它应该要求返回一个 Certification 类型的对象。我显然不理解这里关于泛型的基本知识 - 我有什么问题吗?

更新2:

我按照 @DStanley 尝试了以下操作 - 这也无法编译:

public class Animal
{

    public T BuildList<T>(T list, AttributeModel model) where T : Animal
    {
        return new Animal();
    }
}
Run Code Online (Sandbox Code Playgroud)

D S*_*ley 7

因为约束表明T 源自 Certification。它并没有说T Certification

让我们替换Certification为不同的类型,看看它是否更有意义:

public T BuildList<T>(T list, AttributeModel model) where T : Animal
{
    return new Animal("", "", "");
}
Run Code Online (Sandbox Code Playgroud)

现在如果你打电话怎么办Dog d = BuildList<Dog>()?该方法将返回一个Animal,而不是Dog

编译器知道该方法应该返回 a ,T但实际上它返回的是 a Certification,如果T Certification,则该方法有效,但如果是派生自 的T类型,则无效。您可以返回更具体的类型,但不能返回不太具体的类型: Certification

public Dog getThing<Dog>()
{
    return new Animal(); // obviously fails - an Animal is not necessarily a Dog
    return (Dog)(new Animal()); // This will _compile_ but will fail at runtime since the Animal is not a Dog
}

public Animal getThing<Animal>()
{
    return new Dog();  // Dog is a type of Animal so this is fine.
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下,返回类型应该是Certification,还是应该以某种方式返回类型的对象,T从上下文中不清楚。

我读到“where T : Certification”意味着该方法也可以读作:

   public Certification BuildList(Certification list, AttributeModel model)
Run Code Online (Sandbox Code Playgroud)

T 仅当 Certification调用该方法时,这才是正确的。由于它是通用的,因此可以为继承自 的任何类型调用该方法Certification,因此如果您有

public class MyCertification : Certification;
Run Code Online (Sandbox Code Playgroud)

并将其用于T(意味着您调用var o = BuildList<MyCertification>(...))该方法现在实际上变为:

public public MyCertification BuildList(MyCertification list, AttributeModel model) 
{
    return new Certification("", "", "");
} 
Run Code Online (Sandbox Code Playgroud)

因为Certification不是 a MyCertification(就像泛型Animal不是 a一样Dog),这会失败。

编译器要求从该方法返回的任何内容都派生自T(NOT Certification)。由于Certification不会从本身派生自 的类型派生Certification,因此编译器会告诉您返回类型无效。

  • @AlexeiLevenkov 已更新。这很有趣。我以为我错过了一些基本的东西。但看来我有一个根本性的误解。我想知道我做错了什么。TIA。 (2认同)