我有这个:
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?
}
为什么第二个代码块无法编译,即使返回类型是IClub
?这不公平吗?
我知道我没有充分利用上述代码中类型约束的潜力,但是什么是让代码运行的替代方法?
答案 0 :(得分:1)
T在编译时是一个未知类型,并且编译器无法知道它们是否可以从一种类型转换为另一种类型,因此您明确地要求对该类型进行强制转换。
return (T)(object)(new Arsenal());
这样,编译器确信阿森纳可以作为对象进行转换,并且该对象可以转换为T. 如果转换无效,您将获得运行时断言,但如果转换正确,它将编译并正常工作。
如果你把它限制在IClub,为什么不知道?因为任何类型都可以实现此接口。你试图回归阿森纳,但另一个类,让我们说“Car:IClub”也实施了IClub。在这种情况下,T可以是Car,但是编译器无法证明Arsenal可以被投入Car ...或任何其他类,因为它只知道它实现了哪个接口,而不是它的真实身份。
答案 1 :(得分:1)
这是因为在编译时编译器不知道Arsenal
是否可以转换为T
。 T
可能是另一种实现IClub
的类型。就像GetTeam<WhateverTeam>()
一样。 WhateverTeam
实施IClub
,但您无法将Arsenal
转换为GetTeam<WhateverTeam>()
。
如果您希望编译代码(如Marc-André的答案),则必须转换结果,但您应该重新考虑您的设计(同时调用{{1}}会导致异常)。如果您已经知道将返回哪种类型,那么使该方法通用是没有意义的。