昨天中午米有帶電腦去工作室 拿著c#本質論啃了章<<委託與lambda運算式>>
發現現在對這些理解起來已經不吃力了
不過最後它講運算式lambda和運算式樹狀架構這塊時 還是有點小疑問 可能是我有點鑽牛角 也就是一個是被轉成了泛型委派 一個被轉成了運算式樹狀架構 可以變成其它資料(如sql語句) 不過對這個的機制還不是特別清楚 另外感覺它講IEnumable和IQuerable時沒有突出立即執行和順延強制 這可能是後續linq的內容了 所以這章沒有突出吧 感覺有點小失望啊
--------------------------------------------------------------------------------------------------------------------------
委託是啥?
以下為msdn上的原話
委託是一種引用方法的類型。一旦為委託分配了方法,委託將與該方法具有完全相同的行為。委託方法的使用可以像其他任何方法一樣,具有參數和傳回值.
與委託的簽名(由傳回型別和參數組成)匹配的任何方法都可以分配給該委託。這樣就可以通過編程方式來更改方法調用,還可以向現有類中插入新代碼。只要知道委託的簽名,便可以分配自己的委託方法。
將方法作為參數進行引用的能力使委託成為定義回調方法的理想選擇。例如,可以向排序演算法傳遞對比較兩個對象的方法的引用。分離比較代碼使得可以採用更通用的方式編寫演算法。
我們就來看看它上面說的排序演算法怎麼用委託實現
以下為我寫的一段範例程式碼,用了冒泡排序
對比較方法寫了一個委託 可以做成升序或降序排序
Code:
- public delegate bool CompareTwo(int a, int b);
-
- internal class Compare
- {
- public static bool CompareASC(int first, int second)
- {
- if (first > second)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
-
- public static bool CompareDESC(int a, int b)
- {
- if (a < b)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
-
- }
- internal class Sort
- {
-
- public static void SortList(List<int> list,CompareTwo compareTwo)
- {
-
-
- 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;
- }
- }
- }
-
- }
-
- class Program
- {
- static void Main(string[] args)
- {
- List<int> nums=new List<int>();
- int i = 10;
- while (i>0)
- {
- int a = Int32.Parse(Console.ReadLine());
- nums.Add(a);
- i--;
- }
-
- Sort.SortList(nums,Compare.CompareDESC);
-
- foreach (var num in nums)
- {
- Console.Write(num);
- }
-
- Console.ReadKey();
- }
- }
委託定義
Code:
- public delegate bool CompareTwo(int a, int b);
很明顯 我聲明了一個傳回值為bool 形參為兩個int形的委託!
以形參的形式傳遞方法
Code:
- public static void SortList(List<int> list,CompareTwo compareTwo)
-
- {
這裡我把它方法用委託做成了一個形參的形式 傳給了另一個方法 以達到使用者可以自選使用升序還是降序來排序
以方法傳參時 就這樣做就可以 這是c#2.0及以上版本的寫法!
Code:
- Sort.SortList(nums,Compare.CompareDESC);
c#1.0時 需要先執行個體化委託 要這麼寫
Code:
- Sort.SortList(nums,new CompareTwo(Compare.CompareDESC));
來看看委託的一些實際運用
1 在兩表單之間進行重新整理資料
我在一表單中開啟了另一個表單 在另一個表單中我想要重新整理前一個表單中的TextBox 這時就可以用上委託了
form2中的代碼
Code:
- public delegate void Refresh(string str);
-
- public Refresh RefreshTextBox;
- public Form2()
- {
- InitializeComponent();
- }
-
- private void button1_Click(object sender, EventArgs e)
- {
- this.RefreshTextBox("Hello World!");
- }
form1中的代碼
Code:
- public Form1()
- {
- InitializeComponent();
- }
-
- private void Form1_Load(object sender, EventArgs e)
- {
-
- }
-
- private void button1_Click(object sender, EventArgs e)
- {
- Form2 f2=new Form2();
- f2.RefreshTextBox = this.RefreshTestBox;
- f2.ShowDialog();
-
- }
-
- public void RefreshTestBox(string str)
- {
- this.textBox1.Text = str;
- }
這個還有種辦法能實現跨表單重新整理 就是把當前視窗的this指標傳給下一個視窗 直接在下個視窗調用前一個視窗的方法即可
form2代碼
Code:
- private Form1 form1;
- public Form2(Form1 f1)
- {
- form1 = f1;
- InitializeComponent();
- }
-
- private void button1_Click(object sender, EventArgs e)
- {
- form1.RefreshTestBox("Hello!!!");
- }
form1代碼
Code:
- private void button1_Click(object sender, EventArgs e)
- {
- Form2 f2=new Form2(this);
- f2.ShowDialog();
-
- }
-
- public void RefreshTestBox(string str)
- {
- this.textBox1.Text = str;
- }
委託也可以代替一些介面回調的地方(表單重新整理的第二種方法就類似於介面回調)
2 用委託實現觀察者模式
在用介面回調時 觀察者模式把觀察者觀察被觀察者 理解成 被觀察者通知觀察者 似乎更加說得通一些
其實它是在執行個體化被觀察者時將觀察者的指標當做參數傳入被觀察者中 然後在被觀察者中用觀察者的指標調用觀察者的方法! 如果這裡不用介面 直接拿觀察者做為被觀察者的構造方法(也可以是其它方法)的形參 也是行得通的(不過這樣耦合就變高了 不利於維護與擴充)! 這種情況就和表單重新整理一模一樣了!
3 在多線程中運用得也比較多
貓米有怎麼寫過多線程的程式 這裡就不舉例了