C#委托基础

时间:2023-01-22 04:27:15
 
 
C#委托基础1——委托基础
 

委托和其委托的方法必须具有相同的签名。签名相同:1.参数类型相同 2.参数数量相同 3.返回值一致

例一

  1. class Program
  2. {
  3. public delegate int MathMethod(int x, int y);
  4. public int Add(int a, int b)
  5. {
  6. return a + b;
  7. }
  8. static void Main(string[] args)
  9. {
  10. MathMethod mm;
  11. Program p = new Program();
  12. mm = p.Add;// 相当于一个方法的容器
  13. Console.WriteLine("计算结果为{0}",mm(7,6));
  14. Console.ReadLine();
  15. }
  16. }

例二

  1. class Program
  2. {
  3. public delegate double MathMethod(double x, double y);
  4. double Add(double a, double b)
  5. {
  6. return a + b;
  7. }
  8. double Subtract(double a, double b)
  9. {
  10. return a + b;
  11. }
  12. double Multiply(double a, double b)
  13. {
  14. return a * b;
  15. }
  16. double Divide(double a, double b)
  17. {
  18. return a / b;
  19. }
  20. void DoCalculate(MathMethod mm)
  21. {
  22. Console.WriteLine("请输入第一个数");
  23. double x = Convert.ToDouble(Console.ReadLine());
  24. Console.WriteLine("请输入第二个数");
  25. double y = Convert.ToDouble(Console.ReadLine());
  26. Console.WriteLine("结果{0}",mm(x, y));
  27. Console.ReadLine();
  28. }
  29. static void Main(string[] args)
  30. {
  31. MathMethod mm;
  32. Program p = new Program();
  33. mm = p.Divide;
  34. p.DoCalculate(mm);
  35. }
  36. }

-----------------------------------------------------------

C#委托基础2——多路委托

多路委托

  1. class Program
  2. {
  3. public delegate void SayThingToS(string s);
  4. void SayHello(string s)
  5. {
  6. Console.WriteLine("你好{0}", s);
  7. }
  8. void SayGoodBye(string s)
  9. {
  10. Console.WriteLine("再见{0}", s);
  11. }
  12. static void Main(string[] args)
  13. {
  14. // 方式一
  15. SayThingToS say1, say2, say3, say4;
  16. Program p = new Program();
  17. say1 = p.SayHello;
  18. say1("xy"); // 你好xy
  19. say2 = p.SayGoodBye;
  20. say2("xy"); // 再见xy
  21. say3 = say1 + say2;
  22. say3("xy"); // 你好xy,再见xy
  23. say4 = say3 - say1;
  24. say4("xy"); // 再见xy
  25. // 方式二
  26. SayThingToS s1 = new SayThingToS(p.SayHello);
  27. s1 += new SayThingToS(p.SayGoodBye);
  28. s1("xy"); // 你好xy,再见xy
  29. SayThingToS s2 = new SayThingToS(p.SayHello);
  30. s2 += new SayThingToS(p.SayGoodBye);
  31. s2 -= new SayThingToS(p.SayHello);
  32. s2("xy"); // 再见xy
  33. }
  34. }

-----------------------------------------------------------

C#委托基础3——泛型委托

泛型委托

  1. class Program
  2. {
  3. // 泛型委托,与普通委托类似,不同之处只在于使用泛型委托要指定泛型参数
  4. public delegate T MyGenericDelegate<T>(T obj1,T obj2);
  5. int AddInt(int x, int y)
  6. {
  7. return x + y;
  8. }
  9. string AddString(string s1, string s2)
  10. {
  11. return s1 + s2;
  12. }
  13. static void Main(string[] args)
  14. {
  15. Program p = new Program();
  16. MyGenericDelegate<int> intDel;
  17. intDel = p.AddInt;
  18. Console.WriteLine("int代理的值是{0}", intDel(100, 200));
  19. MyGenericDelegate<string> stringDel;
  20. stringDel = p.AddString;
  21. Console.WriteLine("string代理的值是{0}", stringDel("aaa", "bbb"));
  22. }
  23. }

为了方便开发,.NET基类库针对在实际开发中最常用的情形提供了几个预定义好的委托,这些预定义委托用得很广,比如在编写lambda表达式和开发并行计算程序时经常要用到他们。就是下面我的几篇博客需要介绍的内容。

-----------------------------------------------------------

C#委托基础4——泛型委托Func

为了方便开发,.NET基类库针对在实际开发中最常用的情形提供了几个预定义好的委托,这些预定义委托用得很广,比如在编写lambda表达式和开发并行计算程序时经常要用到他们。

预定义泛型委托Func

  1. class Program
  2. {
  3. double AddInt(int x, int y)
  4. {
  5. return x + y;
  6. }
  7. string AddString(string s1, string s2)
  8. {
  9. return s1 + s2;
  10. }
  11. static void Main(string[] args)
  12. {
  13. Program p = new Program();
  14. // 以为前两个参数为int,他们运行的结果为double,最后一个参数与AddInt返回值一致
  15. Func<int, int, double> funcInt = p.AddInt;
  16. Console.WriteLine("funcInt的值为{0}", funcInt(100, 300));
  17. Func<string, string, string> funcString = p.AddString;
  18. Console.WriteLine("funcString的值为{0}", funcString("aaa", "bbb"));
  19. }
  20. }

-----------------------------------------------------------

C#委托基础5——泛型委托Action

为了方便开发,.NET基类库针对在实际开发中最常用的情形提供了几个预定义好的委托,这些预定义委托用得很广,比如在编写lambda表达式和开发并行计算程序时经常要用到他们

对于函数返回值为空的情形,可以使用Action泛型委托

  1. class Program
  2. {
  3. // 对于函数返回值为空的情形,可以使用Action泛型委托
  4. void Showstring(string s)
  5. {
  6. Console.WriteLine("显示的string值为{0}",s);
  7. }
  8. static void Main(string[] args)
  9. {
  10. Program p = new Program();
  11. Action<string> showstring = p.Showstring;
  12. showstring("xy");
  13. }
  14. }

-----------------------------------------------------------

C#委托基础6——泛型委托Predicate
 

此委托返回一个bool值,该委托通常引用一个"判断条件函数"。

需要指出的是,判断条件一般为“外部的硬性条件”,比如“大于50”,而不是由数据自身指定,不如“查找数组中最大的元素就不适合”。

例一

  1. class Program
  2. {
  3. bool IsGreaterThan50(int i)
  4. {
  5. if (i > 50)
  6. return true;
  7. else
  8. return false;
  9. }
  10. static void Main(string[] args)
  11. {
  12. Program p=new Program();
  13. List<int> lstInt = new List<int>();
  14. lstInt.Add(50);
  15. lstInt.Add(80);
  16. lstInt.Add(90);
  17. Predicate<int> pred = p.IsGreaterThan50;
  18. int i = lstInt.Find(pred);                         // 找到匹配的第一个元素,此处为80
  19. Console.WriteLine("大于50的第一个元素为{0}",i);
  20. List<int> all = lstInt.FindAll(pred);
  21. for (int j = 0; j < all.Count(); j++)
  22. {
  23. Console.WriteLine("大于50的数组中元素为{0}", all[j]);  // 找出所有匹配条件的
  24. }
  25. Console.ReadLine();
  26. }
  27. }

例二

  1. class Staff
  2. {
  3. private double salary;
  4. public double Salary
  5. {
  6. get { return salary; }
  7. set { salary = value; }
  8. }
  9. private string num;
  10. public string Num
  11. {
  12. get { return num; }
  13. set { num = value; }
  14. }
  15. public override string ToString()
  16. {
  17. return "Num......" + num + "......" + "......" + "Salary......" + salary;
  18. }
  19. }
  20. class Program
  21. {
  22. bool IsSalaryGreaterThan5000(Staff s)
  23. {
  24. if (s.Salary > 5000)
  25. return true;
  26. else
  27. return false;
  28. }
  29. static void Main(string[] args)
  30. {
  31. Program p = new Program();
  32. List<Staff> allStaff = new List<Staff>
  33. {
  34. new Staff{Num="001",Salary=9999.9},
  35. new Staff{Num="002",Salary=8991},
  36. new Staff{Num="003",Salary=10000.8},
  37. new Staff{Num="004",Salary=4999.99}
  38. };
  39. Predicate<Staff> s = p.IsSalaryGreaterThan5000;
  40. Staff theFirstOne = allStaff.Find(s);
  41. Console.WriteLine(theFirstOne);              // 找出第一个
  42. List<Staff> all = allStaff.FindAll(s);
  43. for (int i = 0; i < all.Count(); i++)
  44. {
  45. Console.WriteLine(all[i]);               // 找出所有满足条件的
  46. }
  47. Console.ReadLine();
  48. }
  49. }

-----------------------------------------------------------

C#委托基础7——匿名方法
 
 
  1. class Program
  2. {
  3. double AddInt(int x, int y)
  4. {
  5. return x + y;
  6. }
  7. string AddString(string s1, string s2)
  8. {
  9. return s1 + s2;
  10. }
  11. static void Main(string[] args)
  12. {
  13. Program p = new Program();、
  14. // 以为前两个参数为int,他们运行的结果为double,最后一个参数与AddInt返回值一致
  15. Func<int, int, double> funcInt = p.AddInt;
  16. Console.WriteLine("funcInt的值为{0}", funcInt(100, 300));
  17. Func<string, string, string> funcString = p.AddString;
  18. Console.WriteLine("funcString的值为{0}", funcString("aaa", "bbb"));
  19. // 匿名方法
  20. Func<float, float, float> fucFloat = delegate(float x, float y)
  21. {
  22. return x + y;
  23. };
  24. Console.WriteLine("funcFloat的值为{0}", fucFloat(190.7F, 99999.9F));
  25. Console.ReadLine();
  26. }
  27. }

-----------------------------------------------------------

C#委托基础8——lambda表达式

  1. class Program
  2. {
  3. double AddInt(int x, int y)
  4. {
  5. return x + y;
  6. }
  7. string AddString(string s1, string s2)
  8. {
  9. return s1 + s2;
  10. }
  11. static void Main(string[] args)
  12. {
  13. Program p = new Program();
  14. // 以为前两个参数为int,他们运行的结果为double,最后一个参数与AddInt返回值一致
  15. Func<int, int, double> funcInt = p.AddInt;
  16. Console.WriteLine("funcInt的值为{0}", funcInt(100, 300));
  17. Func<string, string, string> funcString = p.AddString;
  18. Console.WriteLine("funcString的值为{0}", funcString("xy", "xy"));
  19. // 匿名方法
  20. Func<float, float, float> fucFloat = delegate(float x, float y)
  21. {
  22. return x + y;
  23. };
  24. Console.WriteLine("funcFloat的值为{0}", fucFloat(190.7F, 99999.9F));
  25. // Lambda表达式
  26. Func<string, string, string> funString2 = (x, y) => (x + y);
  27. Console.WriteLine("funString2的值为{0}", funString2("xy", "xy"));
  28. Console.ReadLine();
  29. }
  30. }

-----------------------------------------------------------

C#委托基础9——Invoke与委托

例一

  1. delegate void AppendStringCallback(string text);
  2. private void AppendString(string txt)
  3. {
  4. this.listView1.Items.Add(txt);
  5. }
  6. private void ReceiveDate()
  7. {
  8. AppendStringCallback appendStringCallback = new AppendStringCallback(AppendString);
  9. this.Invoke(appendStringCallback, new object[]
  10. { string.Format("{0},{1},{2}", str1, str2 + "号", iepAddress.ToString()) });
  11. }

例二

  1. namespace ThreadPoolDemo
  2. {
  3. public partial class ThreadForm : Form
  4. {
  5. // 定义delegate以便Invoke时使用
  6. private delegate void SetProgressBarValue(int value);
  7. // 跟SetProgressBarValue委托相匹配的方法
  8. private void SetProgressValue(int value)
  9. {
  10. progressBar.Value = value;
  11. }
  12. // 使用Invoke方法来设置进度条
  13. private void RunWithInvoke()
  14. {
  15. int value = progressBar.Value;
  16. while (value< progressBar.Maximum)
  17. {
  18. // 如果是跨线程调用
  19. if (InvokeRequired)
  20. {
  21. this.Invoke(new SetProgressBarValue(SetProgressValue), value++);
  22. }
  23. else
  24. {
  25. progressBar.Value = ++value;
  26. }
  27. }
  28. }
  29. public ThreadForm()
  30. {
  31. InitializeComponent();
  32. }
  33. private void btnInvoke_Click(object sender, EventArgs e)
  34. {
  35. progressBar.Value = 0;
  36. Thread thread = new Thread(new ThreadStart(RunWithInvoke));
  37. thread.Start();
  38. }
  39. }
  40. }

-----------------------------------------------------------

C#委托基础系列原于2011年2月份发表在我的新浪博客中,现在将其般至本博客。

本文出自 “IT徐胖子的专栏” 博客,请务必保留此出处http://woshixy.blog.51cto.com/5637578/1070976