1、委托是将方法作为方法的参数。

案例1:常规多态实现

using System;

namespace ConsoleApp1
{
class Program
{
public enum Language {
English,Chinese
}

public static void SayHello(string name, Language lang)
{
switch (lang) {
case Language.English:
EnglishGreeting(name);
break;
case Language.Chinese:
ChineseGreeting(name);
break;
}

}
public static void EnglishGreeting(string name)
{
Console.WriteLine("hello, "+name);
}
public static void ChineseGreeting( string name)
{
Console.WriteLine("你好," + name);
}

static void Main(string[] args)
{
SayHello("laola", Language.English);
SayHello("劳拉", Language.Chinese);
}
}

}

案例1改进:使用委托

using System;

namespace ConsoleApp1
{
class Program
{
public delegate void GreetingDelegate(string name);
//GreetingDelegate可以背用于引用任何一个有单一string 类型参数的方法,并返回void类型的变量。
public static void SayHello(string name, GreetingDelegate greetPeople)
{
greetPeople(name);
}
public static void EnglishGreeting(string name)
{
Console.WriteLine("hello, "+name);
}
public static void ChineseGreeting( string name)
{
Console.WriteLine("你好," + name);
}

static void Main(string[] args)
{
SayHello("laola", EnglishGreeting);
SayHello("劳拉", ChineseGreeting);

Type t = typeof(GreetingDelegate);
Console.WriteLine(t.IsClass);//委托是类,避免在程序中大量使用if-else或switch语句,同时使得程序更好的可拓展性。

}
}

}

C# 委托案例_方法调用

2、实例化委托和内置委托

委托对象可以通过new关键字创建,且与一个特定的方法有关。
当创建委托时,传递到new语句的参数和方法调用一样写,但不带有参数。

//用c++实现同功能
#include<iostream>
using namespace std;
typedef int(*func1)(int x, int y);
int Add(int x, int y) {
return x + y;
}
int Sub(int x, int y) {
return x - y;
}
int main() {
int x = 100, y = 200;
int z = 0;
func1 fun = &Add;
z = fun(x, y);
printf("%d+%d=%d\n",x,y,z);
fun = &Sub;
z = fun(x, y);
printf("%d-%d=%d", x, y, z);
}

一下图片来自中国慕课MOOC

C# 委托案例_类型参数_02


C# 委托案例_方法调用_03

案例:

using System;
//委托时函数指针的升级版
namespace ConsoleApp1
{
class Calculate
{
public int Add(int x,int y)
{
return x + y;
}
public int Sub(int x,int y)
{
return x - y;
}
}
class Program
{
static void Main(string[] args)
{
var g=new Greeting();
Action action1 = new Action(g.SayHello);
action1();
Action<string> action2 = new Action<string>(g.SayHelloToSomeon);
action2("George");

Calculate c = new Calculate();
Func<int, int, int> func1 = new Func<int, int, int>(c.Add);
Console.WriteLine(func1(1,2));
Func<int, int, int> func2 = new Func<int, int, int>(c.Sub);
Console.WriteLine(func2(2, 1));
Console.ReadLine();
}
}

class Greeting
{
public void SayHello()
{
Console.WriteLine("hello ,guys");
}

public void SayHelloToSomeon(string name)
{
Console.WriteLine("hello ,"+name);
}
}

}

C# 委托案例_函数指针_04

3、多播委托

using System;
//委托时函数指针的升级版
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Draw d1 = new Draw() { StuId = 1, PenColor = ConsoleColor.Red,Age=11 };
Draw d2 = new Draw() { StuId = 2, PenColor = ConsoleColor.Green,Age=21 };
Action action1 = new Action(d1.DrawPicture);
Action action2 = new Action(d2.DrawPicture);
//action1();
//action2();
action1 += action2;
action1();//这里是多播委托:可以通过+或- 相同类型进行合并或移除

//Func<int> fun1 = new Func<int>(d1.bornYear);
//Console.WriteLine(fun1());
//fun1 = new Func<int>(d2.bornYear);
//Console.WriteLine(fun1());
//Console.ForegroundColor = ConsoleColor.White;
}
}
class Draw
{
public int StuId{ set; get; }
public ConsoleColor PenColor { set; get; }
public void DrawPicture()
{
Console.ForegroundColor = PenColor;
Console.WriteLine("Student {0} draw a {1}cat", StuId,PenColor);
}
public int Age { set; get; }
public int bornYear()
{
Console.ForegroundColor = PenColor;
return 2020 - Age;
}
}


}