2
  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 的另一个构造和初始化。意思是,在执行此语句后,我们是否会在运行时从泛型类堆栈中获得两个初始化类型?

4

2 回答 2

1

这是否意味着为了使用嵌套委托,它的包含类型必须被初始化(在这种情况下是泛型 Stack 类),而我们需要类型参数参数的原因是因为没有一个,包含泛型类将不会能够构造成一个具体的类,因此不能初始化?

不,包含类型 ( Stack<T>) 不需要初始化。如果您将静态构造函数添加到Stack<T>,那么您将看到它永远不会被您的示例调用。(它会在d被调用时被初始化)你应该知道实际上有无限多的嵌套类型,每个泛型参数类型一个T。类型Stack<int>.StackDelegateStack<float>.StackDelegate运行时完全不同。

这是有效的吗?如果不是,为什么?

是的,它是有效的,因为该方法与委托类型的返回类型和签名相匹配。委托类型Stack<float>.StackDelegate将 afloat[]作为参数,因此与Stack<float>.DoWork. 如果你想要一个不同的类型参数,StackDelegate你必须像这样声明它:

public delegate void StackDelegate<U>(U[] items);

NowStack<int>.StackDelegate<int>是与 不同的类型Stack<float>.StackDelegate<int>,但是这两种委托类型是兼容的,因为它们具有相同的签名和返回类型。

于 2013-04-20T20:38:37.013 回答
0

“DoWork”的类型是void DoWork(int[])(它不使用T),所以它完全匹配w StackDelegate​​hen Tis int

您有可能希望声明DoWork依赖于T

 internal static void DoWork(T[] items) { }

在这种情况下,您将收到预期的编译时错误:

'DoWork' 没有重载匹配委托 'UserQuery.Stack.StackDelegate'

于 2013-04-20T20:23:45.427 回答