【问题标题】:Why can't I return new instance of class specified in generic constraint为什么我不能返回泛型约束中指定的类的新实例
【发布时间】:2015-02-18 13:41:37
【问题描述】:

以下代码无法编译,因为“无法将表达式类型“响应”转换为返回类型“T”

    private T Test<T>() where T : SomeClass
    {
        return new SomeClass();
    }

当您尝试返回约束中指定的类的子类时,错误接缝是合理的,但这里的类型完全相同。这种行为的原因是什么?

【问题讨论】:

  • 你可以反其道而行之:private SomeClass Test&lt;T&gt;() where T : SomeClass, new() { return new T(); }你知道为什么吗?
  • @JeppeStigNielsen 你可以这样做,因为你总是返回基类型,并且任何派生类型都可以隐式转换为这种类型。例如,您有 DerivedClass 并调用返回 DerivedClass 实例的 Test()。由于 DerivedClass 可以隐式转换为 SomeClass ,这是绝对正常的事情。
  • 没错。然后你也可以“看到”你问题中的情况不允许的原因。假设你有private T Test&lt;T&gt;() where T : Animal { return new Animal(); }。然后人们可以做Giraffe g = Test&lt;Giraffe&gt;();。这将导致非特定的Animal 实例被放入Giraffe 类型的变量g。然后g.EatLeaves() 将允许“一般”Animal 实例做一些并非所有动物都能做的事情。
  • 感谢这样的解释性类比。现在看来完全合乎逻辑

标签: c# generics


【解决方案1】:

你不能按照你描述的方式去做,因为如果你有一个派生类,例如

public class SomeDerivedClass : SomeClass 
{
}

您的代码实际上是在尝试执行以下明显不正确的操作:

private SomeDerivedClass Test2()
{
    return new SomeClass();
}

方法return语句中可以返回T类型,只需要在where子句中添加new()约束

private T Test<T>() where T : SomeClass, new()
{
    return new T();
}

【讨论】:

  • 谢谢,答案很明显。我想知道为什么我自己无法弄清楚。
【解决方案2】:

你可以通过添加new()约束来创建一个实例,然后创建一个T的实例

private T Test<T>() where T : SomeClass, new()
{
    return new T();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多