使用泛型类的类型参数的委托
本文关键字:类型参数 泛型类 | 更新日期: 2023-09-27 18:10:05
class Stack<T>
{
T[] items;
int index;
public delegate void StackDelegate(T[] items);
internal static void DoWork(int[] items) { }
}
class TestStack
{
public static void TestSta()
{
Stack<float> s = new Stack<float>();
Stack<int>.StackDelegate d = Stack<float>.DoWork;
}
static void Main()
{
TestSta();
}
}
}
在上面的代码中,非泛型委托是在泛型类中定义的。非泛型委托使用包含类的类型参数。
当引用委托时,我们需要使用定义委托类型的包含类名和包含类的类型参数的类型参数来限定委托类型的名称,否则编译器将无法找到委托。
当我们使用类型参数引用StackDelegate委托时,这是用来构造委托的类型参数吗?
Stack<int>.StackDelegate d = Stack<float>.DoWork;
在这种情况下,使用哪种类型来构造委托?<int>
还是<float>
?
还有,当引用嵌套类型(比如委托)时,类是否初始化,如果是,如何初始化?是否下面的语句Stack<int>.StackDelegate d
导致类Stack被<int>
构造和初始化,然后语句Stack<float>.DoWork;
导致类Stack的另一个构造和初始化?这意味着,在执行这条语句后,我们是否在运行时从泛型类堆栈中获得两个初始化类型?
这是否意味着为了使用嵌套委托,它的包含类型必须初始化(在本例中是泛型Stack类),而我们需要类型参数参数的原因是,如果没有类型参数,包含泛型类将无法构造成具体类,因此将无法初始化?
不,包含类型(Stack<T>
)不需要初始化。如果您向Stack<T>
添加一个静态构造函数,那么您将看到示例永远不会调用它。(它将在调用d
时初始化)您应该意识到实际上有无限多个嵌套类型,每个通用参数类型T
都有一个嵌套类型。Stack<int>.StackDelegate
和Stack<float>.StackDelegate
类型与运行时完全不同。
这个有效吗?如果不是,为什么?
是的,它是有效的,因为该方法匹配委托类型的返回类型和签名。委托类型Stack<float>.StackDelegate
以float[]
作为参数,因此与Stack<float>.DoWork
不兼容。如果你想在StackDelegate
中使用不同的类型参数,你必须这样声明:
public delegate void StackDelegate<U>(U[] items);
现在Stack<int>.StackDelegate<int>
与Stack<float>.StackDelegate<int>
是不同的类型,但是这两种委托类型是兼容的,因为它们具有相同的签名和返回类型。
"DoWork"的类型是void DoWork(int[])
(它不使用T
),所以当T
是int
时,它完全匹配StackDelegate
。
有可能您想要声明DoWork
依赖于T
:
internal static void DoWork(T[] items) { }
在这种情况下,您将得到预期的编译时错误:
DoWork不重载匹配委托UserQuery.Stack.StackDelegate