Rank: มือสมัครเล่น Groups: Member
Joined: 3/4/2008 Posts: 12 Location: thai
|
ไม่ทราบว่า อาจารย์ หรือ พวกพี่ๆท่านใดจะว่างสอน แบบพื้นฐาน-นำไปประยุกต์+ตัวอย่างนิดหน่อยได้บ้างคับ
คือที่มีอยู่มันไม่ได้อธิบายอ่าคับ อยากทราบลักษณะงานที่ใช้ด้วยอะคับ ที่ีมีมันมีแค่โค้ดตัวอย่างไม่มีคำอธิบายเลยอ่าคับ - -"
ปล.ขอบคุณคับ
|
Rank: มือเทพ Groups: Member
Joined: 3/6/2008 Posts: 176 Location: TH
|
delegate ลองดูที่ http://thai-cs.spaces.live.com/ นะครับและก็มี e-book แต่เป็นภาษาอังกฤษถ้าอยากได้ก็บอกนะครับ
|
 Rank: มือมืด Groups: Member
Joined: 3/21/2008 Posts: 53 Location: Whenever you code,you've reached my places.
|
Delegate เป็น immutable object
Delegate คือ type-safed function pointer object
Delegate ทุกตัว สืบทอดจาก System.MulticastDelegate
Delegate สามารถใช้ชี้ไปยังตำแหน่งของ method ที่ต้องการได้ เรียกได้ว่าเป็นตัวแทนของ method ก็ได้
การสร้าง Delegate ก็สามารถทำได้อย่างง่ายดาย ดังนี้
delegate void MyDelegate(string message); // ประกาศตัว delegate
void blahMethod(string message) // นี่คือตัว method ที่เราจะนำ delegate มาห่อหุ้ม (encaps)
{
//do something
}
ต่อไปนี้คือการสร้าง delegate
MyDelegate myDe = blahMethod;
เพียงเท่านี้ myDe ก็จะมี reference ไปยัง blahMethod และเราสามารถที่จะใช้งาน myDe ได้ในลักษณะเดียวกันกับ
blahMethod และได้ผลลัพธ์เหมือนกัน
แต่ delegate ทำให้ เราสามารถ ปฏิบัติกับ method เหมือนกับว่า มันเป็น value
เราสามารถกำหนดให้ delegate ไปอยู่ในตัวแปร ได้
จากที่เห็นของบนก็คือ myDe
รู้จัก delegate ต้องรู้จัก signature ด้วย
signature ในที่นี้หมายถึง method signature เป็นเหมือนสิ่งที่ใช้ระบุตัวตนของ method
เนื่องจากใน class หนึ่งๆ signature ของ methods จะซ้ำกันไม่ได้
โดยที่ methods signature จะสมบัติ bijective ไปยัง method body(หมายถึง 1 to 1 และ เป็น on to) ถ้าอ่านแล้ว งง ข้ามไปก็ได้ เหอะๆ
signature นั้นประกอบไปด้วย ชื่อของ method และ รายการ parameter(type ของมันน่ะไม่รวมชื่อ)
เช่น
void add(int a, int b) --- มี signature คือ ---> add(int,int)
สังเกตดีๆจะเห็นว่าไม่รวม return type เข้าเป้นส่วนนึงของ signature
ดังนั้นจึงเป็นเหตุผลที่ว่าทำใหม่ในคลาสเดียวกันจึงระบบุ แบบนี้ไม่ได
void test();
int test();
float test();
สามตัวนี้อยู่มองเป็น method เดียวกันหมด อยากรุ้ไหมล่ะว่า ทำไม อิอิ คนดีไซน์ภาษานี่มันเก่งโคตระเลย
ฟังแล้วอาจจะไม่มีอะไรมากก็ แค่ไม่รวมเพราะว่า return type อาจจะมีความสัมพันธ์บางอย่าง
ทำให้เกิดสิ่งที่เรียกว่า polymorphism ขึ้นไง เจ๋งปะ
กลับมาเข้าเรื่อง
เอาตัวอย่างอีกสักสองสามอันน่ะ
public static void main(string[] args) ---> signature (ไม่รวม modified ก็จะเหลือแค่ ) ---> main(string[])
int cos(float rad) ->> sign เป็น ->>> cos(float)
น่าจะพอได้แล้วน่ะครับ
ที่นี้กลับมาเข้าเรือ่ง delegate
การจะนำเอา delegate ไปหุ้ม(สังเกตว่าผมใช้คำว่าหุ้มไม่ใช่คำว่า ชี้ เพราะว่ามันมากกว่าชี้ครับ)
การจะนำเอา delegate ไปหุ้ม method ใดๆได้
จะต้องมี return-type และ parameter type ที่เหมือนกันครับ
ก็คือ ถ้าเราต้องการจะสร้าง delegate สำหรับ
double myMed(int a, float b, int c, string d);
เราต้อง declare delegate หน้าตาแบบนี้
double myDelegate(int z, float b, int v, string o); ถึงจะได้
ตัว return-type กับ paremeters-list นี่แหละครับคือ delegate signature ซึ่งค่อนข้างแตกต่างกับ method signature ที่กล่าวมาเพื่อจะบอกว่า
มันเนคนละตัวเท่านั้นเอง
จริงๆเราสามารถ มอง delegate เป็น type ที่ค่อนข้างมีความพิเศษอยู๋สักหน่อยนึงคือ
จะมองเป็น class ก็ได้ หรือจะมองเป็น function (method) ก็ได้
แต่จริงๆแล้วมันก็คือ คลาสที่บรรจุ reference ไปยัง method ที่เราชี้ไปนั่นเอง
การที่เราสามารถเรียก myDelegate(); ได้เลยนั้นเป็นเพียงความสามารถทางด้าน syntax เท่านั้น
โครงสร้างของมันจริงก็คือ ต้องไปเรียก myDelegate.invoke(); นั่นเอง
Delegate(ในปัจจุบันนี้) ทุกตัวสืบทอดจาก System.MulticastDelegate ซึ่งสืบทอดจาก System.Delegate อีกทีนึง
ต่อมาเราจะมาว่ากันต่อเรื่อง MulticastDelegate หรือว่าการทำ DelegateChain
อย่างที่บอกว่าเราสามารถจะใช้ Delegate ชี้ไปยังหลายๆ method ในคราวเดียวกัน(เคยบอกไปยัง ถ้ายังก็กำลังบอกอยู่ไง)
ตัวอย่างเช่น delegate
delegate int exde();
สมมติมี method สองตัว
int aMethod(){ return 3; }
int bMethod(){ return 8; }
exde de = aMethod;
de += bMethod;
de(); // aMethod ทำงาน ตามด้วย bMethod ค่าที่ได้คือ 8 จาก bMethod;
หรือแม้แต่
de = aMethod;
de += aMethod;
de += aMethod;
de(); // aMethod ทำงานสามครั้ง
สิ่งที่เกิดขึ้นคือ
de = aMethod; //ทำการสร้าง instance ของ delegate และชี้ไปยัง aMethod โดยที่ delegate ตัวนี้เป็น immutable object
de ---> (Instance1 of aMethodDelegate)
de += aMethod; // ทำการสร้าง instance ของ delegate และชี้ไปยัง aMethod จากยังสร้าง link ไปยัง delegate ตัวเดิม
// ตัวความที่ delegate เป็น immutable object linklist จึงต้องถูกสร้างจากหลังมาหน้า เพราะไม่สามารถเปลี่ยน state เดิมได้
de ---> (Instance2 of aMethodDelegate) --> (Instance1 of aMethodDelegate)
และ
de ---> (Instance3 of aMethodDelegate) --> (Instance2 of aMethodDelegate) --> (Instance1 of aMethodDelegate)
เมื่อเรา Invoke Delegate chain นี้ มันจะไล่ไปตาม link จนกว่าจะเจอ null link
หรือก็คือตัวสุดท้ายใน linklist หรือก็คือ Instance1 นั่นเอง จากนั้นจึงค่อยทำย้อนกลับขึ้นมา
ผลลัพธ์ก็คือค่าที่ return จาก head ของ linklist หรือก็คือ method สุดท้ายที่เข้าไปอยู่ใน chain
มี class calculator หลักเป็นคลาสเครื่องคิดเลข
เครื่องคิดเลขของคุณมีปุ่มสำหรับคำนวณ โดยจะไปเรียก method calulate
ค่าตัวเลข สองตัว x, y โดยการสุ่มการดำเนินการ อาจจะเป็น + - * / หรือทำหลายๆอย่าง
และต้องรองรับการดำเนินการอื่นๆที่จะถูกส่งเข้ามาในอนาคต
แบบนี้เราไม่สามารถที่จะ fix method ไปในคลาสได้เพราะโจทย์บอกว่าต้องรองรับการดำเนินการอื่นด้วย
เราก็ใช้ delegate เข้ามาช่วย โดยการนิยาม method ดังนี้
delegate double calde(int x, int y);
double calculate(int x, int y, calde de){
return calde(x, y);
}
//method ที่มาเพิ่มในอนาคตจะทำอะไรก็ได้
//ขอให้รับค่า int, int แล้ว return double กลับมา
double Plus(int x, int y){
return x + y;
}
double Power(int x, int y){
return Math.Power(x,y);
}
double Mess(int x, int y){
return x+y*y/2+x*y/x;
}
calde cd1 = Plus;
calde cd2 = Power;
calde cd3 = Mess;
calculate(1,2, cd1);
calculate(4,2, cd2);
calculate(5,5, cd3);
สังเกตว่าเราไม่ต้องเปลี่ยนแปลงหรอืไปยุ่งอะไรกับ calculate เลยแม้แต่นิดเดียว
ที่จริงเราไม่จำเป็นต้องมี source ของ class calculator เลยด้วยซ้ำ
ตัดต่อมาน่ะ ถ้าอ่านแล้วแปร่งๆก็อย่า งง ถามได้
Love = λygh·g(y(y)(h,g), y(y)(h,g))
Code:Love(Love)(I, U) = λgh·g(Love(Love)(h,g), Love(Love)(h,g))(I, U) = λh·I(Love(Love)(h,I), Love(Love)(h,I))(U) = I(Love(Love)(U,I), Love(Love)(U,I)) = I(Love(Love)(U,I)) Love Combinator!!!!
|
Rank: มือเทพ Groups: Member
Joined: 3/6/2008 Posts: 176 Location: TH
|
ไม่น่าจะงงถ้าถ้ามีพื้นฐานมาบ้าง แต่ถ้ามาจาก 0 หรือ 1 นี้อาจจะตามไม่ทันเลยอธิบายได้แทบจะคลอบคลุม delegate เลยขาดไปนิดหน่อยเท่านั้น แต่ก็ไม่ค่อยได้ใช้เท่าไหร่ เรื่องโครงสร้างภายในของมันเท่านั้นเอง ซึ่งตรงนี้จำเป็นมากๆสำหรับ .Net 1.1 แต่ 2.0 ขึ้นไปไม่ใช้ก็ได้ แต่สำหรับเรื่องการทำงานข้าม Thread ถึงแม้จะเป็น 3.5 ก็ยังต้องใช้ delegate แบบโบราณช่วยอยู่บ้างคือต้องเรียก Invoke เอง
|