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

时间:2015-05-08 06:05:34

标签: c# generics delegates

为什么通用代表有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); 
    }    
}

3 个答案:

答案 0 :(得分:7)

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

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

想一想:如果你要使用它:

public delegate void MyGenericDelegate(T arg);

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

答案 1 :(得分:2)

委托是幕后的一个类,需要一个类型说明符是通用的。

你会注意到类的声明如何:

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

答案 2 :(得分:1)

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

public delegate void MyGenericDelegate2(object arg);

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

您可能希望更多地研究泛型:MSDN generics