-
06-12-2008, 11:53 AM #1Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Cách dùng delegate trong lập trình C#
Chào các bạn, nay mình xin làm một bài về tạo một delegate trong C#.
- Delegate là gì? Nó có nghĩa là “ủy quyền”, hay là “ủy thác” nó tựa tựa như là con trỏ hàm trong C/C++ vậy.
- Dùng nó khi mà ta đang ở chổ này, mà cần làm 1 việc gì đó ở chổ khác. Ví dụ đơn giản thế này. Bạn đang ở nhà của nhỏ bạn của bạn, nhỏ đó nhờ bạn sửa bài đồ án cuối kỳ cho nhỏ đó, bạn biết trước được như vậy nên trước khi đi bạn đưa chìa khóa phòng cho nhỏ em gái của mình nhờ nó ”mày cầm chìa khóa phòng anh nè”, xong tự dưng máy của nhỏ bạn đó bị cháy nguồn, giờ phải về phòng bạn làm bài, phòng bạn hết sức là lầy, nhiều rác, tô mì ăn cả tuần chưa rửa [IMG]images/smilies/tongue.png[/IMG]. Bạn alo gọi nhỏ em, “mày qua dẹp phòng cho anh đi, nhỏ bạn mà thây lầy quá nó chán anh thì toi [IMG]images/smilies/biggrin.png[/IMG]”. trong trường hợp này bạn không thể nào tự dẹp phòng mình được, phải nhờ con em nó làm cho vậy bạn đã ủy quyền cho nó 1 hành động nào đó có, bạn không biết là hành động nào trước để mà chuẩn bị, lúc này bạn phải nhờ người khác làm giùm.
- Cũng tương tự như vậy trong lập trình, bạn không thể nào biết được trước trong một số trường hợp là phải tạo thuộc tính nào cho đối tượng của mình (ví dụ bạn tạo 1 usercontrol bạn không thể nào biết được hành động nào ứng với event click chuột vào đó, giả sử click chuột vào đó ở formA bạn cho ra 1 MessageBox, cũng event click chuột lên cái Usercontrol đó ở form khác thì bạn Set cái đoạn text của Usercontrol đó lên form đó).
- Nói dài dòng quá [IMG]images/smilies/tongue.png[/IMG] giờ ví dụ cho các bạn luôn:
Ví dụ khá đơn giản và đã post lên 4rum 1 lần rồi, nay mình post lại 1 lần nữa.
Trên form1 có 2 lable, và 2 button, click vào button1 show form2 lên, form2 có 2 text box, 2textbox của form2 gõ gì, thì 2 lable của form1 show lên cái đó.
Đây là hình của chương trình lúc chưa run.
Bên form 1 bạn code như sau:
Mã:public partial class Form1 : Form{public Form1(){InitializeComponent();} public void GetValue(String str1, String str2){// khai báo 1 hàm với 2 tham số đầu vào là str1, và str2 nó sẽ đưa dữ liệu vào 2 lable label1.Text = str1;label2.Text = str2;}private void button1_Click(object sender, EventArgs e){ Form2 f2 = new Form2();// ké thằng GetValue của form1 vào form2 f2.MyGetData = new Form2.GetString(GetValue); f2.Show(); } private void button2_Click(object sender, EventArgs e) { Application.Exit(); } }
Mã:public partial class Form2 : Form { public Form2() { InitializeComponent(); } // khai báo 1 hàm delegate public delegate void GetString(String MyString1, String MyString2); // khai báo 1 kiểu hàm delegate public GetString MyGetData; private void button1_Click(object sender, EventArgs e) { this.Close(); } private void textBox1_TextChanged(object sender, EventArgs e) { if (MyGetData != null) {// tại đây gọi nó MyGetData(textBox1.Text, textBox2.Text); } } private void textBox2_TextChanged(object sender, EventArgs e) { if (MyGetData != null) {// tại đây cũng gọi nó MyGetData(textBox1.Text, textBox2.Text); } } }
View more random threads:
- Lấy thông tin hệ điều hành (OS Info) trong lập trình C#
- RoleProvider MVC3 (Login Phân Quyền)
- Tập hợp và các thao tác tập hợp trong lập trình C#
- Cài đặt Binary Search Tree bằng C#
- Sử dụng Timer để lấy giờ hệ thống trong lập trình C#
- Vlog 7: Hướng dẫn lập trình: Đọc mail bằng C#
- Video Hướng Dẫn Kết Nối vào Database Và Tạo Form Login Trong C#
- Phím tắt trong Visual Studio 2008 | Tài liệu dạng pdf.
- Series Videos Học lập trình MVC4 Tiếng việt căn bản, nâng cao
- Chuyển đổi các kiểu dữ liệu cơ bản sang mảng Byte trong C#.
-
18-12-2008, 03:26 PM #2Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Mạn phép góp chút ý kiền nha các bạn !
- Theo mình hiểu thì delgate là cơ chế tự động gọi lại 1 hoặc nhiều method. Về hình thức, Delegate là 1 khuôn mẫu mà các method đc gọi lại thông qua Delegate phải theo. VD ta có 1 delegate
public delegate void myDelegate(String, Int16);
Các method muốn đc gọi thông qua phải theo khuôn mẫu mà Delegate đã đặt ra (bao gồm giá trị trả về và danh sách tham số - ko bao gồm tên và modifier). VD:
public void methodToCallBack(String str, Int16 n) {}
Về bản chất, Delegate là 1 class, kế thừa từ MulticastDelegate, nên bạn có thể khai báo 1 Delegate ở bất cứ đâu bạn có thể khai báo 1 class.
- Các method đc gọi lại thông qua Delegate có thể là 1 instance method, cũng có thể là 1 class method.VD:
Mã:class MethodClass{ public void InstanceMethod((String str, Int16 n) {} // (1) static void ClassMethod((String str, Int16 n) {} //(2)}
- Với method (1) bạn tạo 1 wrapper đến method như sau :
Mã:MethodClass onj = new MethodClass ();myDelegate monoDelegate = new myDelegate(obj.InstanceMethod);
Mã:myDelegate monoDelegate = new myDelegate(MethodClass.ClassMethod);
Mã:myDelegate delegate = null;multiDelegate += new myDelegate(obj.InstanceMethod);multiDelegate += new myDelegate(MethodClass.ClassMethod);
VD ta có lệnh gọi :
mutiDelegate(“abc”, 10);
thì lần lượt các method InstanceMethod, ClassMethod sẽ đc gọi với cùng tham số đa truyền vào lệnh gọi đến Delegate (ở đây là 1 String “abc” và 1 Int16 10)
- Theo mình biết thì Delegate thường dùng để gọi lại các method từ 1 method bên khác, thường dùng để tạo các hàm xử lý sự kiện như trong VD của bạn chủ topic
Chút ít ý kiến. Có j sai sót mọng nhận đc ý kiến của các bạn !
Lưu ý để code vào tag code
-
18-12-2008, 05:01 PM #3Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Mình thì lại thấy dùng Delegate để truyền dữ liệu như trên quá là rườm rà.
Bây giờ ví dụ trên form mình lại có thêm những đối tượng khác, chẳng lẽ cứ muốn truyền dữ liệu cho cái nào thì phải tạo một cái delegate tương ứng hay sao?
-
18-12-2008, 05:54 PM #4Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Mình thì lại thấy dùng Delegate để truyền dữ liệu như trên quá là rườm rà.
Bây giờ ví dụ trên form mình lại có thêm những đối tượng khác, chẳng lẽ cứ muốn truyền dữ liệu cho cái nào thì phải tạo một cái delegate tương ứng hay sao?
nó hơi rườm rà nhưng nó khỏe hơn trong 1 số trường hợp
như nếu dùng UserControl thì mình thấy trong 1 số trường hợp, chúng ta dùng delegate thì code sẽ dễ hơn, uyển chuyển hơn... rất nhiều so với dùng properties. [IMG]images/smilies/smile.png[/IMG]
-
18-12-2008, 06:22 PM #5Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Ngoài sử dụng delegate và properties thì vẫn còn 1 số cách để truyền dữ liệu giữa 2 form.Tùy trường hợp mà ta sử dụng thôi.Tham khảo các cách khác ở đây
Mã:http://www.codeproject.com/KB/cs/pass_data_between_forms.aspx
-
19-12-2008, 05:28 PM #6Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
chắc zkday2686 muốn nêu ví dụ đó mà. Chứ thường người ta dùng Delegate để thiết kế event hoặc dùng cho remoting thôi, chứ truyền dữ liệu như vậy thì mệt thiệt [IMG]images/smilies/smile.png[/IMG]
-
20-12-2008, 07:06 PM #7Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Nhanh nhất là truyền thẳng cái đối tượng Form1 vào constructor của Form2.
Thế là truy xuất thoải mái.
-
03-02-2009, 07:30 PM #8Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Mã:public partial class Form1 : Form { public Form1() { InitializeComponent(); } public void GetValue(String str1, String str2) {// khai báo 1 hàm với 2 tham số đầu vào là str1, và str2 nó sẽ đưa dữ liệu vào 2 lable label1.Text = str1; label2.Text = str2; } private void button1_Click(object sender, EventArgs e) { Form2 f2 = new Form2(); // ké thằng GetValue của form1 vào form2 f2.MyGetData = new Form2.GetString(GetValue); f2.Show(); } private void button2_Click(object sender, EventArgs e) { Application.Exit(); } }
-
03-02-2009, 07:44 PM #9Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
tại vì hàm Form2.GetString(...) nhận 1 tham số kiểu delegate. Còn GetValue trong Form2.GetString(GetValue); đóng vai trò là tham số truyền vào thôi chứ không phải là một lời gọi hàm đơn thuần.
Có lẽ bạn chưa hiểu về Delegate, mình lấy ví dụ thế này cho bạn dễ hiểu nhé.
Ta có một method FindMax tìm số lớn nhất như sau:
Mã:void int FindMax(int[] myArray);{ int max = myArray[0]; foreach (int i in myArray) { if (i > max) max = i; } return max;}
Mã:void int FindMax(Array myArray)
Mã:static object FindMax(Array myArray, CompareHandler compare) { object max = myArray.GetValue(0); foreach (object obj in myArray) { if (compare(obj, max) > 0) max = obj; } return max; }
Mã:delegate int CompareHandler(object a, object b);
Như vậy là bạn đã làm xong hàm FindMax tìm phần tử lớn nhất trong 1 mảng tổng quát.
Vậy sau này khi dùng ta chỉ cần định nghĩa 1 hàm compare cho kiểu dữ liệu mảng tương ứng đó thôi.
Mã:static int CompareInt(object a, object b) { return (int)a - (int)b; } static int CompareString(object a, object b) { return ((string)a).CompareTo((string)b); } static void Main() { CompareHandler compareDelegate = null; int[] arrInt = { 1, 2, 5, 10, 3, 6 }; compareDelegate = CompareInt; int maxInt = (int)FindMax(arrInt, compareDelegate); Console.WriteLine("max = {0}", maxInt); string[] arrStr = { "1", "2", "5", "10", "3", "6" }; compareDelegate = CompareString; string maxStr = (string)FindMax(arrStr, compareDelegate); Console.WriteLine("max = {0}", maxStr); }
-
08-08-2009, 06:49 PM #10Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
cho mình hỏi là mình dùng cái này vào trong việc login được không?
Nghĩa là khi login xong thì tên người login sẽ được hiển thị trên các form khác ý?
Thông qua phân tích dữ liệu Google từ 86 quốc gia, mới đây, một công ty tại Anh đã công bố bảng xếp hạng kích tấc "cậu nhỏ" của các nước trên thế giới. Kết quả, hầu hết các nước xếp ở nhóm đầu của...
"Chim" của chàng trai Việt thuộc...