为什么通用委托有 DelegateName<T>(T arg)?为什么不是 DelegateName(T arg)

Why do generic delegates have DelegateName<T>(T arg)? Why not DelegateName(T arg)

为什么通用委托有 DelegateName<T>?为什么不 DelegateName(T arg)

参数已经指定了类型,那么为什么委托名称还要跟在<T>之后,这是命名约定,还是开发人员知道它接受整数或目的是什么这样的 C# 语法?

public delegate void MyGenericDelegate<T>(T arg);

Main()
{
    // Register targets.      
    MyGenericDelegate<string> strTarget = new MyGenericDelegate<string>(StringTarget);      
    strTarget("Some string data");  

    MyGenericDelegate<int> intTarget =  new MyGenericDelegate<int>(IntTarget);      
    intTarget(9);  

    static void StringTarget(string arg) 
    {      
        Console.WriteLine("arg in uppercase is: {0}", arg.ToUpper());  
    }  

    static void IntTarget(int arg)   
    {       
        Console.WriteLine("++arg is: {0}", ++arg); 
    }    
}

委托是幕后的 class,需要类型说明符才能通用。

您会注意到 class 的声明如何:

class MyList {
    T[] items; 
}

无效,因为 T 在该上下文中是未知的。出于同样的原因,委托需要类型声明 - T 无法解析为类型。


考虑 public delegate void MyDel<T>(T arg); - 检查发出的 IL 可能很有趣:

.class public auto ansi sealed ConsoleApplication20.MyDel`1<T>
    extends [mscorlib]System.MulticastDelegate
{
    // Methods
    .method public hidebysig specialname rtspecialname 
        instance void .ctor (
            object 'object',
            native int 'method'
        ) runtime managed 
    {
    } // end of method MyDel`1::.ctor

    .method public hidebysig newslot virtual 
        instance void Invoke (
            !T arg
        ) runtime managed 
    {
    } // end of method MyDel`1::Invoke

    .method public hidebysig newslot virtual 
        instance class [mscorlib]System.IAsyncResult BeginInvoke (
            !T arg,
            class [mscorlib]System.AsyncCallback callback,
            object 'object'
        ) runtime managed 
    {
    } // end of method MyDel`1::BeginInvoke

    .method public hidebysig newslot virtual 
        instance void EndInvoke (
            class [mscorlib]System.IAsyncResult result
        ) runtime managed 
    {
    } // end of method MyDel`1::EndInvoke

} // end of class ConsoleApplication20.MyDel`1

为了声明您正在用作参数类型的类型参数的存在 arg,您需要使您的方法通用。使其通用需要使用以下语法:

public delegate void MyGenericDelegate<T>(T arg);

想一想:如果你要使用这个:

public delegate void MyGenericDelegate(T arg);

这声明了一个委托类型,它按字面意思接受 T 类型的参数。编译器会查看当前的命名空间和导入的命名空间,并尝试找到类型 T,如果找不到,你会得到一个编译器错误。

问题是您想使用强类型委托。所以基本上要么你使用

public delegate void MyGenericDelegate2(object arg);

public delegate void MyGenericDelegate<T>(T arg);

您可能想进一步研究泛型:MSDN generics