我有这个代码作为一个例子:
class A<T> {
public class B : A<long> {
public void f() {
Console.WriteLine( typeof(T).ToString());
}
public class C : A<long>.B { }
}
}
class Prg5 { static void Main() {
var c = new A<float>.B.C();
c.f();
} }
与输出:
System.Int64
为什么要长时间打印?最初传递的float类型如何以及在哪里被替换?
类型C
定义为:
public class C : A<long>.B { }
类型A
定义为:
class A<T> {
public class B : A<long> {
public void f() {
Console.WriteLine( typeof(T).ToString());
}
public class C : A<long>.B { }
}
}
所以如果你创建一个新的C
,那么A
的类型参数是long
。
语句var c = new A<float>.B.C();
、A<float>
和B
只是"路径"的一部分。到嵌套类C
。A<float>
是该路径的一部分这一事实并不会改变C
是A<long>.B
的事实。
参数float
和B
是A<long>
的事实与确定c.f()
内部的T
的类型无关。
答案
当你调用f
时,你在A<T>
中,T
是long
,因为B
是A<long>
,所以T
是long
。
我明白为什么它看起来很奇怪:你期望T
是float
,但事实上,因为B
是A<long>
,B
是A<T>
,其中T
是long
。
因为C
是B
的子节点,所以它是B
的扩展同类型,所以是A<long>
.
因此,输出long
而不是为外部类的泛型类型参数指定的float
的封闭构造类型的结果。
因此,无论创建实例时指定的T
是什么,您将始终获得f
中T
类型的long
。
解决
这是一个有点复杂的递归,我认为,但你不只是需要它吗?
class A<T>
{
public class B : A<T>
{
public void f()
{
Console.WriteLine(typeof(T).ToString());
}
public class C : B { }
}
}
这样写:
var c = new A<float>.B.C();
c.f();
将输出:
System.Single
阅读泛型打开和关闭构造类型
构造类型.NET中的泛型
泛型(c#编程指南)
c#泛型Level 1
c#泛型Level 2