为什么通用委托有 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
为什么通用委托有 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