使用泛型类的类型参数的代理

时间:2013-04-20 20:19:32

标签: c# generics delegates

  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();
        }
    }
}

在上面的代码中,非泛型委托是在泛型类中定义的。非泛型委托使用包含类的类型参数。

当引用委托时,我们需要使用包含定义委托类型的类名和包含类的type参数的类型参数来限定委托类型的名称,否则编译器将无法使用找到代表。

当我们使用类型参数引用StackDelegate委托时,是否是用于构造委托的类型参数?

 Stack<int>.StackDelegate d = Stack<float>.DoWork;

在这种情况下,哪种类型用于构造委托? <int><float>

此外,是在引用嵌套类型(例如委托)时初始化的类,如果是,如何? 以下语句Stack<int>.StackDelegate d是否导致类堆栈<int>被构造和初始化,然后语句Stack<float>.DoWork;导致类Stack的另一个构造和初始化。这意味着,在执行此语句后,我们是否在运行时从泛型类堆栈中获取了两个初始化类型?

2 个答案:

答案 0 :(得分:1)

  

这是否意味着为了使用嵌套委托,必须初始化其包含类型(在本例中为泛型Stack类),以及我们需要类型参数参数的原因,因为没有一个,包含泛型class不能构造成具体的类,因此无法初始化?

不,包含类型(Stack<T>)不需要初始化。如果向Stack<T>添加静态构造函数,那么您将看到样本从未调用过它。 (它将在调用d时初始化)您应该知道实际上存在无限多的嵌套类型,每个通用参数类型T一个。类型Stack<int>.StackDelegateStack<float>.StackDelegate与运行时完全不同。

  

这有效吗?如果没有,为什么?

是的,它是有效的,因为该方法匹配委托类型的返回类型和签名。委托类型Stack<float>.StackDelegatefloat[]作为参数,因此与Stack<float>.DoWork不兼容。如果你想在StackDelegate中使用不同的类型参数,你必须这样声明:

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

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

答案 1 :(得分:0)

“DoWork”的类型为void DoWork(int[])(它不使用T),因此当StackDelegateT时,它与int完全匹配。

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

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

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

  

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