什么是委托?
如果我们需要把方法作为参数来传递的话,就需要用到委托。简单来说,委托就是一个类型,这个类型可以被赋值一个方法的引用(也即是说可以讲一个方法赋值给一个委托实例,这样的话,我们成这个委托实例指向这个方法)。
委托声明和使用
在c#中,使用一个类型,分类两个部分。首先定义一个类型,这个过程会告诉编译器,这个类型由哪些变量和方法组成,其次就是通过类型实例化对象。
编译器在编译的时候,其实是把委托编译成类型。所以使用委托其实就是使用类型。首先定义委托,同样这个过程是告诉编译器,这个委托指向的方法的样式,其次是通过委托创建实例对象。
具体委托使用示例代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace C_Sharp_Demo { /// <summary> /// 本class讲述知识点 /// 1.委托的基础使用,共两种方式 /// 2.将委托作为方法参数传递 /// </summary> class Delegate1 { //声明了一个委托,这个委托指向的方法返回值是string类型,并且这个方法没有参数,这个委托的名称叫GetAString private delegate string GetAString(); //声明了一个委托,这个委托指向的方法返回值是void类型,并且这个方法没有参数。这个委托的名称是GetMethod public delegate void GetMethod(); static void Main(string[] args) { int a = 40; /*----------第一种委托的使用方式--------*/ //使用委托类型创建委托实例,s指向a的ToString方法。 //但是注意"a.ToString"语句并没有调用ToString方法,只是指向他 GetAString s = new GetAString(a.ToString); //在这儿通过委托调用a的ToString方法,跟直接调用a.ToString()是一样的效果 string ss = s(); /*-------------------------------------*/ /*-----------第二种委托的使用方式---------*/ //将a的ToString方法赋值给s1这个委托实例 GetAString s1 = a.ToString; //通过s1的Invoke方法使用委托 string ss1 = s1.Invoke(); /*---------------------------------------*/ Console.WriteLine(ss); Console.WriteLine(ss1); /*------------将委托作为方法的参数传递-----------*/ //将method1赋值给委托实例method GetMethod method = method1; //将委托实例method作为printMethod的参数 printMethod(method); method = method2; printMethod(method); /*---------------------------------------*/ Console.ReadKey(); } /** * 该方法需要GetMethod委托类型作为参数 * */ public static void printMethod(GetMethod method) { method.Invoke(); } public static void method1() { Console.WriteLine("method1"); } public static void method2() { Console.WriteLine("method2"); } } }
Action委托,Func委托
Action和Func委托是系统库预置的两种委托。这两种委托之间有一些区别,使用方式大同小异。
Action委托的使用方式跟我们自定义的委托使用相同,但是不同之处在于Action委托只能指向void类型返回值的方法,可以指定泛型,泛型代表着Action委托指向的方法的参数类型,如果不加泛型表示所指向方法没有返回值。
例如:
/*---------------Action委托1--------------*/
//Action所指向的方法不能有返回值(也即是返回类型为void)
Action action = actionMethod;
action();
例如:
/*---------------Action委托1--------------*/
//Action所指向的方法不能有返回值(也即是返回类型为void)
Action action = actionMethod;
action();
//Action指向该方法,所以该方法没有返回值,Action不指定泛型,所以该方法不能有参数
public static void actionMethod() {
Console.WriteLine("action");
}
public static void actionMethod() {
Console.WriteLine("action");
}
/*---------------------------------------*/
/*---------------Action委托2--------------*/
//Action指定泛型代表着所指向方法的参数类型
Action<int, int> action1 = actionMethod1;
action1(22, 33);
Action<int, int> action1 = actionMethod1;
action1(22, 33);
//Action<int,int>指向该方法,所以该方法没有返回值,Action<int,int>了指定泛型<int,int>,所以该方法必须有两个int型参数
public static void actionMethod1(int a, int b) {
Console.WriteLine(a + b);
}
public static void actionMethod1(int a, int b) {
Console.WriteLine(a + b);
}
/*---------------------------------------*/
Func委托必须指定泛型,Func委托所指向的方法必须有返回值,Func委托必须指定泛型,泛型列表的最后一个参数类型代表着所指向方法的返回值类型,最后一个类型前面的代表着所指向方法的参数类型。
例如:
/*---------------Func委托--------------*/
//最后一个泛型代表着所指向方法funcMethod的返回值类型为string,前面的泛型代表着所指向方法funcMethod的参数类型
Func<int, int, string> func = funcMethod;
//funcMethod的参数为两个int,所以访问时要传入两个int类型参数
string result = func(2,3);
//最后一个泛型代表着所指向方法funcMethod的返回值类型为string,前面的泛型代表着所指向方法funcMethod的参数类型
Func<int, int, string> func = funcMethod;
//funcMethod的参数为两个int,所以访问时要传入两个int类型参数
string result = func(2,3);
//Func<int, int, string>指向该方法,所以该方法必须有string类型返回值,并且参数也是由前面的泛型所决定
public static string funcMethod(int a, int b)
{
return (a + b).ToString() + " funcMethod !";
}
/*---------------------------------------*/
public static string funcMethod(int a, int b)
{
return (a + b).ToString() + " funcMethod !";
}
/*---------------------------------------*/