为什么我不能返回泛型类型约束中指定类型的东西,但可以在没有约束的情况下返回相同的类型?

时间:2012-10-18 06:18:42

标签: c# type-inference return-type generic-constraints

我有这个:

public IClub GetTeam()
{
    return new Arsenal();
}
//compiles since Arsenal is an IClub

public T GetTeam<T>() where T : IClub, new()
{
    return new Arsenal();
}
//wouldn't compile saying "cannot convert Arsenal to T"

但这些事情有效:

public T GetTeam<T>() where T : IClub, new()
{
    T t = new T();
    t.Sponsor = "Nike"; //since it knows T is IClub,
    return new T();     //but why the injustice to return type alone?
}
  1. 为什么第二个代码块无法编译,即使返回类型是IClub?这不公平吗?

  2. 我知道我没有充分利用上述代码中类型约束的潜力,但是什么是让代码运行的替代方法?

2 个答案:

答案 0 :(得分:1)

T在编译时是一个未知类型,并且编译器无法知道它们是否可以从一种类型转换为另一种类型,因此您明确地要求对该类型进行强制转换。

return (T)(object)(new Arsenal());

这样,编译器确信阿森纳可以作为对象进行转换,并且该对象可以转换为T. 如果转换无效,您将获得运行时断言,但如果转换正确,它将编译并正常工作。

如果你把它限制在IClub,为什么不知道?因为任何类型都可以实现此接口。你试图回归阿森纳,但另一个类,让我们说“Car:IClub”也实施了IClub。在这种情况下,T可以是Car,但是编译器无法证明Arsenal可以被投入Car ...或任何其他类,因为它只知道它实现了哪个接口,而不是它的真实身份。

答案 1 :(得分:1)

这是因为在编译时编译器不知道Arsenal是否可以转换为TT可能是另一种实现IClub的类型。就像GetTeam<WhateverTeam>()一样。 WhateverTeam实施IClub,但您无法将Arsenal转换为GetTeam<WhateverTeam>()

如果您希望编译代码(如Marc-André的答案),则必须转换结果,但您应该重新考虑您的设计(同时调用{{1}}会导致异常)。如果您已经知道将返回哪种类型,那么使该方法通用是没有意义的。