1.委托将方法作为变量传递
private delegate string GetAString();
static void Main(string[] args)
{
int x = 40;
GetAString a = new GetAString(x.ToString);
string str = a();
}
private delegate string GetAString();
static void Main(string[] args)
{
int x = 40;
GetAString a = x.ToString;
string str = a.Invoke();
Console.WriteLine(str);
Console.ReadKey();
}
这里声明了一个委托方法GetAString,将GetAString实例化,a指向了ToString方法
2.声明一个委托,可以将委托作为函数的参数传递。
委托的实质是创造了一个类,
创建委托的实例是调用了构造函数
static void Main(string[] args)
{
PrintString method = Method1;
PrintStr(method);
method = Method2;
PrintStr(method);
Console.ReadKey();
}
private delegate void PrintString();
static void PrintStr(PrintString print)
{
print();
}
static void Method1()
{
Console.WriteLine("Method1");
}
static void Method2()
{
Console.WriteLine("Method2");
}
3.Action委托和Func委托
Action是一个预定义的委托类型,可以指向一个没有返回值没有参数的方法
在Action的委托类型后面定义一个泛型,委托会根据泛型自动寻找匹配方法
Func委托有返回值,返回值类型由泛型指定
Func后面可以跟很多类型,最后一个类型是返回值类型,前面的类型是参数类型,参数类型必须和指向的方法的参数类型按照顺序对应
static int Test1(string str)
{
Console.WriteLine(str);
return 100;
}
static void Main(string[] args)
{
Func a = Test1;
int str = a("a");
Console.WriteLine(str);
Console.ReadKey();
}
4.用Func委托加泛型拓展冒泡排序
先创建一个静态的排序的方法,使用泛型,将泛型的要比较的数组传入,再传入一个委托的方法,这个方法有两个参数返回值就是两个数比较大小一个·bool值,
static void CommomSort(T[] sortArray,Func compareMethod)
{
bool swapped = true;
do
{
swapped = false;
for (int i = 0; i < sortArray.Length - 1; i++)
{
if (compareMethod(sortArray[i], sortArray[i + 1]))
{
T temp = sortArray[i];
sortArray[i] = sortArray[i + 1];
sortArray[i + 1] = temp;
swapped = true;
}
}
} while (swapped);
}
这个方法再要对比的类中定义的,比较两个员工的工资大小,返回值是bool
public static bool Compare(Employee a1,Employee a2)
{
bool n;
if (a1.Salary>a2.Salary) { return true; }
return false;
}
在Main函数中,创建了一个集合,调用CommonSort的方法,传入employees数组和比较的方法。
static void Main(string[] args)
{
Employee[] employees = new Employee[]
{
new Employee("a", 16),
new Employee("b", 12),
new Employee("c", 36)
};
CommomSort(employees,Employee.Compare);
foreach (Employee em in employees)
{
Console.WriteLine(em.Name+" : "+em.Salary);
}
Console.ReadKey();
}
5.多播委托
委托指向多个方法
static void Test1()
{
Console.WriteLine("test1");
}
static void Test2()
{
Console.WriteLine("test2");
}
static void Main(string[] args)
{
Action a = Test1;
a += Test2;
a();
Console.ReadKey();
}
取得多播委托中所有的方法
通过GetIncocationList方法得到委托中的所有方法返回一个Delegate的集合
6.匿名方法
一个匿名方法没有名字,任何使用委托变量的地方都可以使用匿名方法赋值
Func plus = delegate (int arg1, int arg2)
{
return arg1 + arg2;
};
7.Lambda表达式
Lambda表达式不需要声明类型
Func addB = b => b + 1;
Lambda表达式左面列出参数
8.
事件
在声明委托变量的前面加上关键字event,就是一个事件只能作为一个类的变量 ,事件不能在类的外部触发
观察者设计模式:
一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。
Cat为被观察者、Mouse为观察者
先定义一个Cat和一个Mouse类,在Cat类中添加委托的方法,在Cat Coming中调用委托的方法。
在Main函数中,将mouse类中的run添加进入委托方法。这样在调用CatComing的时候就会调用观察者的方法。
并且不会因为添加了新的观察者而改变被观察者的代码。
class Cat
{
private string name;
public Cat(string name)
{
this.name = name;
}
public void CatComing()
{
Console.WriteLine(name + "is coming");
catComing();
}
public Action catComing;
}
}
class Mouse
{
private string name;
public Mouse(string name)
{
this.name = name;
}
public void Run()
{
Console.WriteLine(name + " run");
}
}
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat("jiafei");
Mouse mouse1 = new Mouse("miki");
cat.catComing += mouse1.Run;
Mouse mouse2 = new Mouse("milaoshu");
cat.catComing += mouse2.Run;
cat.CatComing();
Console.ReadKey();
}
}