Archive
Delegates and Events ตอนที่ 3
สวัสดีครับ คิดว่าคงมี สักคนที่ได้มีโอกาสอ่าน blog ผม ก็เลยสวัสดีไปงั้นแหละ สำหรับตอนนี้เป็น การพูดถึง delegates ต่อจากตอนที่แล้ว ครับ ซึ่งเราคงจะได้เข้าใจการใช้งาน delegates ไม่มากก็น้อย สำหรับในตอนนี้ จะพูดถึงเรื่อง Multicast delegates ครับ delegates สามารถที่จะอ้างอิง function หรือ method ได้มาก กว่าหนึ่งนะครับนี่ นั่นก็คือ delegates object หนึ่งตัวสามารถที่จะอ้างอิง ไปยัง หลาย ๆ method และเมื่อเรียก delegates นั้นก็ทำให้ method ที่มันอ้างอิงอยู่ ทำงานในคราวเดียวกัน ครับ
ครับจากที่ได้กล่าวมา ข้างต้น delegates นั้นที่จริงแล้วเป็น multicast ก็หมายถึงโดยปกติแล้วมันสามารถที่จะชี้ไปยัง function หรือ method ได้หลาย method หรือ function ในคราวเดียวกัน Base case ของ multicast delegates ก็คือ System.MulticastDelegate ครับ ดังนั้น การเรียก delegates object ครั้งเดียวก็สามารถที่จะสั่งให้ หลาย method ทำงานได้ แต่ต้องไม่ลืมนะครับว่า Method เหล่านั้นต้องเป็นไปตามข้อกำหนดของ delegates นะครับ นี้สำคัญ นะครับ 🙂
Delegates and Events ตอนที่ 1
Class ต่าง ๆ เป็น Reference type หมายถึง ตัวแปรของ Obeject ของ Class นั้น ไม่ได้อ้างอิงไปยัง Object โดยตรง แต่ชี้ไปยังที่ตำแหน่งใน Address ของ Object แทน ซึ่งทำให้เราสามารถใช้งาน Object ในรูปแบบพิเศษได้มากมาย Delegates ก็เป็นตัวแปรอีกชนิดหนึ่งที่เป็นลักษณะ Reference type Deletgates นั้น สามารถที่จะชี้ไปยัง Method หรือ Reference ไปยัง Method ได้ในขณะ runtime นั่นก็หมายถึงเราสามารถ ที่จะเลือกได้ว่า เราจะ สั่ง Method ไหนทำงานก็ได้ ในขณะ runtime ขึ้นอยู่กับ ความต้องการในขณะนั้น
ในส่วนนี้ผมจะพูดถึงเรื่อง การสร้าง Deletgates การทำ multicast delegates และ วิธีการใช้ event กับ delegates
Deletgates เป็นตัวแปร แบบ Reference type สามารถที่จะอ้างอิงไปยัง method ใด ๆ ก็ได้ delegate ใน C# คล้ายกับ function pointer ใน C++ เพื่อให้เกิดความเข้าใจ พิจารณาจาก code ต่อไปนี้
// Delegate declaration public delegate void MyDelegate(string ArgValue); public void DelegateFunction(string PassValue) { // Method implement here } public void UseMethod() { // Delegate Instantiation MyDelegate DelegateObject = new MyDelegate(DelegateFunction); }
จาก code ด้านบน บรรทัดแรกคือการประกาศ delegate สังเกตุรูปแบบของการประกาศเป็นไปตาม syntax นี้
delegate <return type> <delegate-name> <parameter list>
จาก code ตัวอย่าง delegate ชื่อ MyDelegate ไม่ return ค่าและมี parameter 1 ตัวคือ PassValue ซึ่งมีชนิดเป็น string สำหรับ function ที่เราจะทำ delegate ก็จะต้อง มีการกำหนด signature ให้ตรงกับ delegate ที่ประกาศไว้ จากตัวอย่าง คือ function ถัดมา ชื่อว่า DelegateFunction ซึ่งได้มีการประกาศ signature ไว้ตรงกับ delegate ด้านบนทุกประการ หลังจากนั้น การใช้งานเราจำทำการ instantiate Delegate object คล้ายกับการ Instantiat object ของ Class เพียงแต่ว่า นี้เป็น object ที่เป็นdelegate โดยจะส่งชื่อ function ที่ต้องการเป็น Parameter ของ delegate constructure
Mydelegate DelegatObject = new MyDelegate(DelegateFunction);
หลังจากนั้น การใช้งานเราสามารถที่จะเรียก DelegateObject แทนชื่อ function ได้เลยและเป็นลักษณะ reference สามารถที่จะส่งผ่าน DelegateObject เป็น argument ของfunctionใด ๆ ที่ต้องการใช้ function เป็น parameter ไ้ด้เลย ซึ่งจะไ้้้่ด้เห็นการใช้งานในรูปแบบต่าง ๆต่อไป
การใช้งาน Delegate
เพื่อให้เห็น ภาพมากขึ้นจะขอยกตัวอย่างการเรียกใช้ function ปกติขึ้นมาพิจารณาเพื่อนำไปสู่การใช้งาน ขอให้พิจารณาจากตัวอย่างนี้นะครับ
namespace MyNameSpace.NoDelegate { public class MyClass { public void Process() { Console.WriteLine("Process() begin"); Console.WriteLine("Process() end"); } } public class Test { static void Main(string[] args) { MyClass myClass = new MyClass(); myClass.Process(); } } }
จาก ตัวอย่าง เป็นการใช้งานทั่วไปสำหรับการเรียกใช้ function สมมุติว่าถ้าหากเราไม่ต้องการเรียกใช้ function ตรง ๆ หล่ะหากเราต้องการที่จะส่งผ่าน function นี้ให้กับ function อื่นเรียกใช้อีกที โดยเฉพาะการทำงานในลักษณะ event-driven เรามาดูการ ใช้ delegate จากตัวอย่างเดียวกัน
Very basic delegate
namespace ConsoleApplication1 { public class MyClass { public delegate void WriteHandler(string message); public void Process(WriteHandler writeh) { writeh("Process() begin"); writeh("Process() end"); } public void writer(string message) { Console.WriteLine(message); } } public class Program { static void Main(string[] args) { MyClass myclass = new MyClass(); MyClass.WriteHandler writehander = new MyClass.WriteHandler(myclass.writer); myclass.Process(writehander); } } }
ผลของการ ทำงาน จะได้เช่นเดียวกับโปรแกรมแรกนะครับ แต่โปรแกรมนี้เราใช้คุณลักษณะของ delegate พิจารณา class Myclass จะเห็นว่ามีการ ประกาศ Delegate ชื่อ ว่า WriteHandler มี parameter 1 ตัวคือ message และไม่มีการ return ค่าดังนั้น function ที่เราต้องการทำ delegation คือ writer สังเกตุว่า มี signature เหมือนกัน
หลังจากนั้น เราต้องการส่งผ่านฟังก์ชันนี้เขาไปทำงานใน method ชื่อ Process นะครับ สังเกตุว่า Parameter ของ Process นั้นเป็นชนิดเดียวกับ delegate
แล้วสุดท้ายเ้รามาดูที่ class program ที่ Main เราจะเห็นว่า จะมีการ instantiate delegate object ชื่อ writehander แล้วส่ง method ชื่อ writer เป็น argument ผลก็คือได้ writerhandler ที่อ้างอิงไปยัง writer เราก็โยน writerhandler เข้าไปให้ Process เป็นการส่งผ่าน parameter แบบ reference นะครับ จะเห็นว่าการทำงานครั้งนี้ เราส่งผ่าน function หรือ method เป็น parameter นะครับ นี่แหละการทำงานของ delegate ครับ จะเห็นว่าการทำงานของ delegate นั้นมีขั้นตอนดังนี้นะครับ
- Delclaration
- Instantiation
- Invocation
จากตัวอย่างที่แล้ว หลายท่านที่เป็น มือใหม่อาจจะยังมึน ๆ ขอตบท้ายด้วย ตัวอย่าง ง่าย ๆ อีกหนึ่งตัวอย่างนะครับ
using System; namespace Mynamespace.BasicDelegate { // #1 Declaration public delegate void SimpleDelegate(); class TestDelegate { public static void MyFunc() { Console.WriteLine("I was called by delegate ..."); } public static void Main() { // #2 Instantiation SimpleDelegate simpleDelegate = new SimpleDelegate(MyFunc); // #3 Invocation simpleDelegate(); } } }
เป็นงั้ยครับ พอจะได้ concept ใหม่ครับ ลอง run code ดูนะครับแล้วจะเข้าใจ สำหรับ delegate ขอพอแค่นี้ก่อนนะครับ ขอให้ติดตาม ในตอน ต่อ ๆไปนะครับเนื่องจากมีการใช้งานอีก หลายลักษณะ ขอให้มีความสุขกับการเรียนรู้นะครับ