定义委托
使用关键字delegate,委托是没有函数体的
public delegate string GetString();
使用委托类型创建实例
一般使用第二种创建实例的写法
int x = 10;
string y = x.ToString();//把x转换成string字符换
//使用委托类型,创建实例
GetString a = new GetString(x.ToString);//a指向了x中的Tostring方法
GetString a = x.ToString;//这是另外一种使用委托类型的写法。
//因为不是调用ToString方法,所以是不需要些括号的。
通过委托调用方法
通过委托类型调用一个方法,跟直接调用方法的作用是一样的。
string y = a();
通过Invoke方法调用a中引用的方法,跟上面方法作用一样。
string y = a.Invoke();
委托就是把方法当作参数进行传递,上面代码就是把x的Tostring方法传递到a中,给a赋值了x.Totring的方法引用。
委托既能使用静态static方法,也能使用普通方法。
使用委托类型作为方法的参数
public delegate void PrintStrng();
public static void Print(PrintStrng print)//print就相当于一个方法(把委托当成参数用)
{
print();//其实这里的print()等于是Method1()的方法
}
public static void Method1()
{
Console.WriteLine("调用了Method1");
}
public static void Method2()
{
Console.WriteLine("调用了Method2");
}
上面代码就是先创建了PrintString委托,在创建一个静态方法Print,把委托类型PrintString的print当作参数进行传递。再新建两个静态方法Method1和Method2,
PrintStrng method = Method1;//把Method1的引用赋值给了method
Print(method);
把Method1的引用赋值给了method,method再作为参数传递给Print方法。控制台输出结果:
可以看出控制台给出的是Method1方法中的内容。
Action委托
Action是系统内置(预定义)的一个委托类型,它可以指向一个没有参数和没有返回值的方法
static void PrintString()
{
Console.WriteLine("aa");
}
Action a = PrintString;
定义了一个委托类型,这个类型没有返回值,但是有一个int参数的方法
static void PrintInt(int i)
{
Console.WriteLine(i);
}
Action<int> a = PrintInt;
定义了一个委托类型,这个类型没有返回值,但是有一个string参数的方法,这里有两个相同名字的方法,系统会自动寻找匹配的方法
static void PrintString()
{
Console.WriteLine("aa");
}
static void PrintString(string str)
{
Console.WriteLine(str);
}
Action<string> a = PrintString;
Action可以后面通过泛型去指定Action指向方法的多个参数类型,参数类型跟Action后面声明的委托类型对应。
static void PrintDoubleInt(int i1,int i2)
{
Console.WriteLine(i1+i2);
}
Action<int, int> a = PrintDoubleInt;
Func委托
Func中的泛型类型指定的类型是方法的返回值类型
static int Test1()
{
return 1;
}
Func<int> a = Test1;
下面的Func中,int对应Test2中的参数类型,string对应方法返回值类型。
Func<int, string> a = Test2;
static string Test2(int i)
{
return i + "";
}
Func中的泛型类型中可以跟很多类型,最后一个类型表示方法的返回值类型,前面得到类型是参数类型,参数类型必须跟指向的方法参数类型对应。
Func后面必须跟有一个返回值类型,参数类型可以有0-16个,先写参数类型,最后写方法方法返回类型
多播委托(多路广播委托)
其调用列表中可以拥有多个元素的委托
static void Test1()
{
Console.WriteLine("test1");
//throw new Exception();//抛出异常,整个迭代就会停止
}
static void Test2()
{
Console.WriteLine("test2");
}
Action a = Test1;//定义一个Action委托
a += Test2;//通过“+=”传递多个方法的引用到a中。同理“-=”表示删除引用
if (a != null)
{
a();//当委托没有指向任何方法时候 ,调用会出现异常null
}
通过“+=”传递多个方法的引用到a中,同理“-=”表示删除引用
此时使用GetInvocationList方法取得多播委托中所有的方法,返回的是Delegate类型的数组
Delegate[] delegates = a.GetInvocationList();
通过遍历返回的Delegate类型数组来进行逐一调用,使用DynamicInvoke函数单独调用
foreach (var temp in delegates)//遍历多播委托中所有的方法
{
temp.DynamicInvoke();//并使用DynamicInvoke()函数单独调用。
}