当遇到在运行时才能决定用哪种方法的时候,使用委托。
可以把delegate看做一个包含有序方法列表的对象,这些方法具有相同的签名和返回类型。
定义一个委托
<访问修饰符> delegate <返回类型> <委托名> (<参数列表>)
访问修饰符不是必须的
public delegate int MyDelegate (int s);
委托的例子
using System;
namespace 委托
{
delegate void MyDel(int value);//声明委托类型
class MainClass
{
public static void Main(string[] args)
{
MainClass mainClass = new MainClass();
MyDel del;//声明
//随机产生一个0-99之间的随机数
Random random = new Random();
int randomValue = random.Next(99);
del = (randomValue < 50)
? new MyDel(mainClass.PrintLow)
: new MyDel(mainClass.PrintHigh);//xxx ? xxx : xxx
del(randomValue);//执行委托
}
void PrintLow(int value)
{
Console.WriteLine("{0} - Low Value", value);
}
void PrintHigh(int value)
{
Console.WriteLine("{0} - High Value", value);
}
}
}
委托也可以有泛型
可以这样实例化,委托对象必须使用 new 关键字来创建,声明变量并创建类型的对象。
public delegate void printString(string s);
。。。
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
或这样
printString ps1;
ps1 = WriteToScreen;
还可以不取名字,不单独写函数,如果是只需要用一次的情况,这样可以更方便
printString = delegate (int a) {
函数体
}
组合委托
MyDel delA = myInstObj.MyM1;
MyDel delB = SClass.otherM2;
MyDel delC = delA + delB;
代码创建了三个委托,第三个委托由前两个委托组合而成。
多播
委托对象可使用 "+" 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。
使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播。
public delegate void Greeting (string name);
public static void ChineseGreeting(string name)
{
Console.WriteLine (name + "先生你好!");
}
public static void JapaneseGreeting(string name)
{
Console.WriteLine ("{0}さん、こんにちは",name);
}
GreetingDelegate greet;
greet = ChineseGreeting;
greet += JapaneseGreeting;
greet ("李");
这样会输出
李先生你好!
李さん、こんにちは
当然用-=就会去掉,不过如果去掉本来没在greet里面的,比如写greet -= EnglishGreeting也不会报错
调用带返回值的委托
using System;
namespace 委托
{
delegate int MyDel();//声明委托类型
class MainClass
{
public static void Main(string[] args)
{
MyClass myClass = new MyClass();
MyDel del = myClass.Add1;//创建并初始化
del += myClass.Add2;//增加方法
del += myClass.Add1;//增加方法
Console.WriteLine("Value:{0}", del());
}
}
class MyClass
{
int value = 5;
public int Add1()
{
value += 2;
return value;
}
public int Add2()
{
value += 3;
return value;
}
}
}
//结果为12
Lambda表达式
下面的效果一样
using System;
namespace 委托
{
delegate double MyDel(int par);//声明委托类型
class MainClass
{
public static void Main(string[] args)
{
MyDel del = delegate(int x) {
return x + 1;
};
MyDel del1 = (int x) =>
{
return x + 1;
};
MyDel del2 = (x) =>
{
return x + 1;
};
MyDel del3 = x =>
{
return x + 1;
};
MyDel del4 = x => x + 1;
}
}
}
Lambda表达式和委托的小例子
using System;
namespace ConsoleApp1
{
class Example
{
public int Plus1(int a, int b)
{
return a + b;
}
public int Plus2(int a, int b) => a + b;
public void Plus3(int a, int b) => Console.WriteLine(a + b);
public delegate int DeleLambdaEmpty();
public delegate int DeleLambdaOne(int a);
public delegate int DeleLambdaTwo(int a, int b);
static Func<string, string, string> GetFunc = (p1, p2) => { return p1 + " " + p2; };
public static Func<int, int, bool> testForEquality = (x, y) => x == y;
static void Main()
{
Example example = new Example();
Console.Write("Plus1(1, 2):");
Console.WriteLine(example.Plus1(1, 2));
Console.Write("Plus2(1, 2):");
Console.WriteLine(example.Plus2(1, 2));
Console.Write("Plus3(1, 2):");
example.Plus3(1, 2);
DeleLambdaEmpty deleLambdaEmpty = () => { return 0; };
Console.Write("DeleLambdaEmpty():");
Console.WriteLine(deleLambdaEmpty());
DeleLambdaOne deleLambdaOne = a => { return a; };
Console.Write("DeleLambdaOne():");
Console.WriteLine(deleLambdaOne(1));
DeleLambdaTwo deleLambdaTwo = (a,b) => { return a + b; };
Console.Write("DeleLambdaTwo():");
Console.WriteLine(deleLambdaTwo(1,1));
Console.Write("testForEquality(1,2):");
Console.WriteLine(testForEquality(1, 2));
var c = GetFunc(example.Plus1(1, 2).ToString(), example.Plus1(3, 4).ToString());
Console.Write("GetFunc():");
Console.WriteLine(c);
Console.ReadKey();
}
}
}