委托
- 委托(delegate)是一种存储函数引用的类型。
- 委托的定义指定了一个返回类型和一个参数列表。
- 定义了委托之后,就可以声明该委托类型的变量,接着就可以把一个返回类型跟参数列表跟委托一样的函教赋值给这个变量。
- 委托的使用分两步:
- 结构体,枚举的使用同上都分为定义和声明。
- 整数类型、数组类型、字符串类型都是直接声明变量的,因为类型的定义已经完成了(CLR中已经完成定义)。
什么是委托
举例一:调用静态方法
namespace MyDelegate
{
internal class Program
{
static double Multiply(double num1,double num2)
{
return num1 * num2;
}
static double Divide(double num1, double num2)
{
return num1/num2;
}
delegate double MyDelegate(double num1, double num2);
static void Main(string[] args)
{
MyDelegate myDelegate = Multiply;
Console.WriteLine(myDelegate(4,2));
myDelegate=Divide;
Console.WriteLine(myDelegate(4,2));
}
}
}
举例二:调用实例化方法
static void Main(string[] args)
{
Student s1= new Student(18);
MYDelegate mYDelegate = s1.say;
mYDelegate();
}
delegate void MYDelegate();
class Student
{
private int Id { get; set; }
public Student(int id)
{
Id = id;
}
public void say()
{
Console.WriteLine("我今年{0}岁了!",Id);
}
}
举例三:委托当参数使用
namespace MyDelegateDemo
{
internal class Program
{
delegate void OnDieDelegate();
static void Play(OnDieDelegate onDie)
{
Console.WriteLine("做任务");
Console.WriteLine("玩家正在战斗");
Console.WriteLine("死亡");
if(onDie!=null)
{
onDie();
}
}
static void ShowDieUI()
{
Console.WriteLine("显示玩家死亡后的UI");
Console.WriteLine("返回首页");
}
static void Main(string[] args)
{
Play(ShowDieUI);
Play(null);
}
}
}
委托类型数组
static double Multiply(double num1,double num2)
{
return num1 * num2;
}
static double Divide(double num1, double num2)
{
return num1/num2;
}
delegate double MyDelegate(double num1, double num2);
static void Main(string[] args)
{
Console.WriteLine("=============");
MyDelegate[] myDelegates = {Multiply,Divide };
foreach(MyDelegate x in myDelegates)
{
Console.WriteLine(x(8,2));
}
}
泛型委托Action、Func
Action演示
private static void test1()
{
Console.WriteLine("这是无参的方法");
}
private static void test2(int x)
{
Console.WriteLine("这是有一个int类型参数的方法");
}
private static void test3(int x,double y)
{
Console.WriteLine("这是有2个参数的方法");
}
static void Main(string[] args)
{
Action method = Program.test1;
method();
Action<int> method2 = Program.test2;
method2(1);
Action<int,double> method3 = Program.test3;
method3(1,1);
}
Func演示
private static int test4()
{
Console.WriteLine("调用了int类的方法");
return 0;
}
private static double test5(double x)
{
**Console.WriteLine("调用了doubl**e类的方法");
return x;
}
static void Main(string[] args)
{
Func<int> func = test4;
func();
Func<double,double> func2 = test5;
func2(6);
}
使用委托升级冒泡排序
namespace test03
{
public class Employee
{
public string Name { get;private set; }
public double Salary { get; set; }
public Employee(string name, double salary)
{
Name = name;
Salary = salary;
}
public static bool Compare(Employee e1, Employee e2)
{
return e1.Salary > e2.Salary;
}
}
}
using System;
namespace test03
{
internal class Program
{
public static void Sort<T>(T[] data, Func<T, T, bool> compare)
{
bool swapped = true;
do
{
swapped = false;
for (int i = 0; i < data.Length - 1; i++)
{
if (compare(data[i],data[i+1]))
{
T temp = data[i];
data[i] = data[i + 1];
data[i + 1] = temp;
swapped = true;
}
}
} while (swapped);
}
public static void Main(string[] args)
{
Employee[] employees =
{
new Employee("aa", 7000),
new Employee("bb", 3000),
new Employee("cc", 2000),
new Employee("dd", 5000),
new Employee("ee", 4000),
new Employee("ff", 1000)
};
Sort<Employee>(employees, Employee.Compare);
foreach (Employee emp in employees)
{
Console.WriteLine(emp.Name+":"+emp.Salary);
}
}
}
}
多播委托
- 前面使用的委托都只包含一个方法的调用,但是委托也可以包含多个方法,这种委托叫做多播委托。
- 使用多播委托就可以按照顺序调用多个方法,多播委托只能得到调用的最后一个方法的结果,一般我们把多播委托的返回类型声明为void。
Delegate[] delegates = action.GetInvocationList();
foreach (Delegate d in delegates)
{
d.DynamicInvoke();
}
案例
internal class Program
{
public static void test1()
{
Console.WriteLine("test1");
}
public static void test2()
{
Console.WriteLine("test2");
}
public static void Main(string[] args)
{
Action action = test1;
action();
Console.WriteLine("====");
action += test2;
action();
Console.WriteLine("====");
action += test2;
action();
Console.WriteLine("====");
action -= test1;
action();
Delegate[] delegates = action.GetInvocationList();
foreach (Delegate d in delegates)
{
d.DynamicInvoke();
}
}
}
匿名方法
Lambda表达式