再看委托

来源:互联网 发布:coc七本兵种升级数据 编辑:程序博客网 时间:2024/05/01 04:36

 昨天中午米有带电脑去工作室 拿着c#本质论啃了章<<委托与lambda表达式>>

发现现在对这些理解起来已经不吃力了 

不过最后它讲表达式lambda和表达式树这块时 还是有点小疑问 可能是我有点钻牛角 也就是一个是被转成了泛型委托 一个被转成了表达式树 可以变成其它数据(如sql语句)  不过对这个的机制还不是特别清楚 另外感觉它讲IEnumable和IQuerable时没有突出立即执行和延迟执行 这可能是后续linq的内容了 所以这章没有突出吧 感觉有点小失望啊

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

委托是啥?

以下为msdn上的原话

委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值.

与委托的签名(由返回类型和参数组成)匹配的任何方法都可以分配给该委托。这样就可以通过编程方式来更改方法调用,还可以向现有类中插入新代码。只要知道委托的签名,便可以分配自己的委托方法。

将方法作为参数进行引用的能力使委托成为定义回调方法的理想选择。例如,可以向排序算法传递对比较两个对象的方法的引用。分离比较代码使得可以采用更通用的方式编写算法。

 

我们就来看看它上面说的排序算法怎么用委托实现

以下为我写的一段示例代码,用了冒泡排序

对比较方法写了一个委托 可以做成升序或降序排序

Code:
  1. public delegate bool CompareTwo(int a, int b);  
  2.   
  3. internal class Compare  
  4. {  
  5.     public static bool CompareASC(int first, int second)  
  6.     {  
  7.         if (first > second)  
  8.         {  
  9.             return true;  
  10.         }  
  11.         else  
  12.         {  
  13.             return false;  
  14.         }  
  15.     }  
  16.   
  17.     public static bool CompareDESC(int a, int b)  
  18.     {  
  19.         if (a < b)  
  20.         {  
  21.             return true;  
  22.         }  
  23.         else  
  24.         {  
  25.             return false;  
  26.         }  
  27.     }  
  28.   
  29. }  
  30. internal class Sort  
  31. {  
  32.   
  33.     public static void SortList(List<int> list,CompareTwo compareTwo)  
  34.     {  
  35.   
  36.          
    •   for(int i=0;i<list.Count-1;i++)   
    •           {   
    •               for (int j = i;  j >=1 ; j--)   
    •               {   
    •                         if(compareTwo(list[j-1],list[j]))   
    •                         {   
    •                             int c;   
    •    
    •                             c = list[j-1];   
    •                             list[j-1] = list[j];   
    •                             list[j] = c;   
    •                         }   
    •               }        
    •           }
  37.     
  38. }  
  39.   
  40. class Program  
  41. {  
  42.     static void Main(string[] args)  
  43.     {  
  44.         List<int> nums=new List<int>();  
  45.         int i = 10;  
  46.         while (i>0)  
  47.         {  
  48.             int a = Int32.Parse(Console.ReadLine());  
  49.             nums.Add(a);  
  50.             i--;  
  51.         }  
  52.          
  53.         Sort.SortList(nums,Compare.CompareDESC);  
  54.   
  55.         foreach (var num in nums)  
  56.         {  
  57.             Console.Write(num);  
  58.         }  
  59.   
  60.         Console.ReadKey();  
  61.     }  
  62. }  

委托定义

Code:
  1. public delegate bool CompareTwo(int a, int b);  

很明显 我声明了一个返回值为bool 形参为两个int形的委托!

 

以形参的形式传递方法

 

 

 

Code:
  1. public static void SortList(List<int> list,CompareTwo compareTwo)  
  2.   
  3.        {  

 

 

这里我把它方法用委托做成了一个形参的形式 传给了另一个方法 以达到用户可以自选使用升序还是降序来排序

以方法传参时 就这样做就可以 这是c#2.0及以上版本的写法!

Code:
  1. Sort.SortList(nums,Compare.CompareDESC);  

c#1.0时 需要先实例化委托 要这么写

Code:
  1. Sort.SortList(nums,new CompareTwo(Compare.CompareDESC));  

 

来看看委托的一些实际运用

1 在两窗体之间进行刷新数据

我在一窗体中打开了另一个窗体 在另一个窗体中我想要刷新前一个窗体中的TextBox 这时就可以用上委托了

form2中的代码

Code:
  1. public delegate void Refresh(string str);  
  2.   
  3.         public Refresh RefreshTextBox;  
  4.         public Form2()  
  5.         {  
  6.             InitializeComponent();  
  7.         }  
  8.   
  9.         private void button1_Click(object sender, EventArgs e)  
  10.         {  
  11.             this.RefreshTextBox("Hello World!");  
  12.         }  

form1中的代码

Code:
  1. public Form1()  
  2. {  
  3.     InitializeComponent();  
  4. }  
  5.   
  6. private void Form1_Load(object sender, EventArgs e)  
  7. {  
  8.   
  9. }  
  10.   
  11. private void button1_Click(object sender, EventArgs e)  
  12. {  
  13.     Form2 f2=new Form2();  
  14.     f2.RefreshTextBox = this.RefreshTestBox;  
  15.     f2.ShowDialog();  
  16.   
  17. }  
  18.   
  19. public void RefreshTestBox(string str)  
  20. {  
  21.     this.textBox1.Text = str;  
  22. }  

效果图

 

这个还有种办法能实现跨窗体刷新 就是把当前窗口的this指针传给下一个窗口 直接在下个窗口调用前一个窗口的方法即可

form2代码

Code:
  1. private Form1 form1;  
  2.        public Form2(Form1 f1)  
  3.        {  
  4.            form1 = f1;  
  5.            InitializeComponent();  
  6.        }  
  7.   
  8.        private void button1_Click(object sender, EventArgs e)  
  9.        {  
  10.               form1.RefreshTestBox("Hello!!!");  
  11.        }  

form1代码

Code:
  1. private void button1_Click(object sender, EventArgs e)  
  2.       {  
  3.           Form2 f2=new Form2(this);  
  4.           f2.ShowDialog();  
  5.   
  6.       }  
  7.   
  8.       public void RefreshTestBox(string str)  
  9.       {  
  10.           this.textBox1.Text = str;  
  11.       }  

委托也可以代替一些接口回调的地方(窗体刷新的第二种方法就类似于接口回调)

 

 

2 用委托实现观察者模式

在用接口回调时 观察者模式把观察者观察被观察者 理解成 被观察者通知观察者 似乎更加说得通一些

其实它是在实例化被观察者时将观察者的指针当做参数传入被观察者中 然后在被观察者中用观察者的指针调用观察者的方法! 如果这里不用接口 直接拿观察者做为被观察者的构造方法(也可以是其它方法)的形参 也是行得通的(不过这样耦合就变高了 不利于维护与扩展)! 这种情况就和窗体刷新一模一样了!

 

3 在多线程中运用得也比较多

猫米有怎么写过多线程的程序 这里就不举例了