【问题标题】:Why cannot I return something of type specified in the generic type constraint but can return the same type without constraint?为什么我不能返回泛型类型约束中指定的类型,但可以在没有约束的情况下返回相同的类型?
【发布时间】:2012-10-18 06:18:42
【问题描述】:

我有这个:

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. 我知道我没有充分利用上述代码中类型约束的潜力,但有什么替代方法可以让代码运行?

【问题讨论】:

  • 为什么不返回 IClub? public IClub GetTeam() where T : IClub, new().
  • @AmitMittal 这类似于问我为什么不使用第一个代码块。我的设计就是为此而迫不及待。我的意思是像阿森纳这样的所有俱乐部都继承了 IClub,上面定义了GetTeam&lt;T&gt;。我知道这不是一个好的设计。我会重新考虑一下

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


【解决方案1】:

这是因为在编译时编译器不知道Arsenal 是否可以转换为T。毕竟T 可能是另一种实现IClub 的类型。比如GetTeam&lt;WhateverTeam&gt;()WhateverTeam 实现了IClub,但您不能将Arsenal 转换为那个。

如果您希望代码编译(如 Marc-André 的回答),您必须转换结果,但您应该重新考虑您的设计(也调用 GetTeam&lt;WhateverTeam&gt;() 会导致异常)。如果您已经知道将返回哪种类型,那么将该方法设为通用是没有意义的。

【讨论】:

  • 这正好解决了这个问题!!谢谢。有时我愚蠢地认为我比语言设计师知道的更多:P
  • 是的,我知道现在的设计很差。再次感谢。
【解决方案2】:

T 在编译时是一个未知类型,编译器无法知道它们是否可以从一种类型转换为另一种类型,因此您需要明确地调用该类型的转换。

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

这样,编译器就可以肯定地知道,Arsenal 可以转换为一个对象,并且该对象可以转换为 T。 如果转换无效,您将获得运行时断言,但如果转换正确,它将编译并正常工作。

如果将 T 限制为 IClub,为什么它是未知的?因为任何类型都可以实现这个接口。您尝试返回阿森纳,但另一个类,假设“汽车:IClub”也实现了 IClub。在这种情况下,T 可以是 Car,但编译器无法证明阿森纳可以转换为 Car... 或任何其他类,因为它只知道它实现了哪个接口,而不是它的真实身份。

【讨论】:

  • 也可以使用(T)(IClub)new Arsenal();。我不确定相对优点是什么,如果有的话。
  • T 在编译时不是未知的,它指定了它的 IClub!这就是我的困惑
  • T 实现 IClub,但不是 IClub。因此,编译器无法知道是否可以将阿森纳转换为实现 IClub 的未知类型。假设阿森纳:IClub 和Arsenal2:IClub。 T是Arsenal2,但Arsenal不能被施法到Arsenal2中。
  • @dbaseman:我猜没有,从句法的角度来看可能更简洁。向下转型只是为了向 T 型向上转型。因为对象是一切的根源,所以我习惯使用它。
  • @nawfal 这个问题让我很困惑,之前我把它作为一个单独的问题提出来。你可能会觉得很有趣:stackoverflow.com/questions/12335757/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多