委托在C#中最经常使用的特性之一,委托可以理解为C中的函数指针,但C#中的委托功能更强,使用更方便,本节总结一下关于C#的委托的使用
1、委托的使用
委托相当于对函数的引用,通过委托可以直接使用该函数
1)定义委托 2)实例化委托 3)使用委托
//定义委托 public delegate int AddDelegate(int a, int b); class Program { static void Main(string[] args) { Program p = new Program(); //实例化委托 AddDelegate adddelegate = new AddDelegate(p.Add); //此时,可以直接使用委托访问Add函数 Console.Write("6 + 8 = {0}", adddelegate(6, 8)); } public int Add(int a, int b) { return a + b; } }
2、泛型委托
//定义委托 public delegate T AddDelegate<T>(T a, T b); class Program { static void Main(string[] args) { Program p = new Program(); //实例化委托 AddDelegate<int> intadddelegate = new AddDelegate<int>(p.IntAdd); AddDelegate<double> doubleadddelegate = new AddDelegate<double>(p.DoubleAdd); Console.Write("6 + 8 = {0}", intadddelegate(6, 8)); Console.Write("6.5 + 8.7 = {0}", doubleadddelegate(6.5, 8.7)); } public double DoubleAdd(double a, double b) { return a + b; } public int IntAdd(int a, int b) { return a + b; } }
3、Func泛型委托
Func泛型委托可以不需要定义委托,直接就可以使用,其中Func泛型委托的最后一个参数为返回值类型
class Program { static void Main(string[] args) { Program p = new Program(); Func<int, int, int> intadd = p.IntAdd; Func<double, double, double> doubleadd = p.DoubleAdd; Console.Write("6 + 8 = {0}", intadd(6, 8)); Console.Write("6.5 + 8.7 = {0}", doubleadd(6.5, 8.7)); } public double DoubleAdd(double a, double b) { return a + b; } public int IntAdd(int a, int b) { return a + b; } }
4、Action泛型委托
Func泛型委托适用于带返回值的委托函数,而无返回值的委托可以用Action泛型委托
class Program { static void Main(string[] args) { Program p = new Program(); Action<string> showmsg = p.ShowString; showmsg("Hello"); } public void ShowString(string msg) { Console.Write("显示:{0}", msg); } }
5、Predicate泛型委托
Predicate泛型委托定义了一组条件,表示指定对象是否符合条件,返回值为bool类型,一般用于查找匹配,看例子就懂了
class Program { static void Main(string[] args) { Program p = new Program(); Predicate<int> numgreatethan10 = p.IsNumGreaterThan10; //定义一组对象 List<int> nums = new List<int> { 2, 3, 5, 8, 12, 25 }; int firstnum = nums.Find(numgreatethan10); //委托作为匹配条件用于查找 List<int> all = nums.FindAll(numgreatethan10); } bool IsNumGreaterThan10(int a) { //判断a是否大于10 if (a > 10) return true; else return false; } }
6、匿名方法
对于一些代码量小的函数,可以通过匿名委托来定义,让代码更简洁
class Program { static void Main(string[] args) { Program p = new Program(); Func<int, int, int> intadd = delegate(int a, int b) { return a + b; }; Console.Write("6 + 7 = {0}", intadd(6, 7)); } }
7、Lambda表达式
比起匿名方法,Lambda表达式更加简洁,只有参数,甚至连参数都可以不写
class Program { static void Main(string[] args) { Program p = new Program(); Func<int, int, int> intadd = (a, b) => { return a + b; }; Console.Write("6 + 7 = {0}", intadd(6, 7)); Console.ReadKey(); } }
8、Invoke与委托
在多线程编程时,后台线程可以通过委托让主线程更新UI,达到交互的目的
1)首先定义一个委托 ProgressUpdate
2)创建一个进度条控件 progressBar1,显示进度
3)创建一个后台线程,通过委托更新进度
public partial class Form1 : Form { public delegate void ProgressUpdate(int i); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //创建线程 new Thread(() => { for (int i = 0; i <= 100; i++) { this.Invoke(new ProgressUpdate(UpdateProgress), i); Thread.Sleep(100); } }).Start(); } private void UpdateProgress(int i) { this.progressBar1.Value = i; } }