泛型的乐趣:没有隐式引用转换错误
Fun with generics: no implicit reference conversion error
我测试了这段代码,发现它无法编译。
interface IE<T>
{
}
class A<T> : IE<T>
{
public static void F<TU>() where TU : IE<T>
{
}
static void Foo()
{
F<A<int>>();
}
}
即使我添加public static void F<TU>() where TU : A<int>, IE<T>
也失败了。
afaik 根据 C# 规范,它是有效的。如果我删除约束 where TU : IE<T>
但在这种情况下它不会影响,因为 A<int>
是 IE<T>
.
的子类型
这也很有趣,因为 resharper 建议将 IE<T>
接口添加到 A
为什么此代码无效?
不,无效。
的约束
where TU : IE<T>
指的是 current T
,即您调用此方法的类型。
考虑调用:
A<string>.Foo();
这试图将 A<int>
作为 TU
的类型参数传递,但约束意味着必须存在从 TU
到 IE<string>
的引用转换,因为T
是 string
.
没有从 A<int>
到 IE<string>
的转换,因此它被破坏了。基本上,您对“A<int>
是 IE<T>
的子类型”的期望并不适用于所有 T
。
现在您可以将其更改为:
public static void F<TU, TT>() where TU : IE<TT>
{
}
static void Foo()
{
F<A<int>, int>();
}
那是现在有效,因为它根本不涉及T
。
我测试了这段代码,发现它无法编译。
interface IE<T>
{
}
class A<T> : IE<T>
{
public static void F<TU>() where TU : IE<T>
{
}
static void Foo()
{
F<A<int>>();
}
}
即使我添加public static void F<TU>() where TU : A<int>, IE<T>
也失败了。
afaik 根据 C# 规范,它是有效的。如果我删除约束 where TU : IE<T>
但在这种情况下它不会影响,因为 A<int>
是 IE<T>
.
这也很有趣,因为 resharper 建议将 IE<T>
接口添加到 A
为什么此代码无效?
不,无效。
的约束where TU : IE<T>
指的是 current T
,即您调用此方法的类型。
考虑调用:
A<string>.Foo();
这试图将 A<int>
作为 TU
的类型参数传递,但约束意味着必须存在从 TU
到 IE<string>
的引用转换,因为T
是 string
.
没有从 A<int>
到 IE<string>
的转换,因此它被破坏了。基本上,您对“A<int>
是 IE<T>
的子类型”的期望并不适用于所有 T
。
现在您可以将其更改为:
public static void F<TU, TT>() where TU : IE<TT>
{
}
static void Foo()
{
F<A<int>, int>();
}
那是现在有效,因为它根本不涉及T
。