C# Delegates Hell (part 1)

ดีจ้า …
สวัสดีครับ เนื่องจากอาทิตย์นี้มีเวลา (และถูกบังคับเล็กๆ) ก็เลยจะขอ Dig deep & break things เรื่อง Delegate ซักหน่อย เพราะว่าตัวผมเองก็ยังไม่แม่น พออ่านโค้ดที่เป็น Delegate แล้วรู้สึกไม่สบายใจ เหมือนมีอะไรคอยเป่าหูให้ไม่ยอมเข้าใจซักที แต่วันนี้ล่ะ ! …

เริ่มกันเลยดีกว่า จะได้ไม่เสียเวลา (เผื่อเนื้อคู่เดินผ่านมา แล้วเรามัวแต่ก้มหน้าอ่านอยู่ จะได้ไม่มาโทษผมในภายภาคหน้า)

ใครเขียน C# คงจะเคยผ่านตากันมาบ้าง สำหรับเจ้า Delegate รูปร่างหน้าตาประมาณนี้

เอิ่ม .. โอเค ไม่เข้าใจอย่างเดิมน่ะดีแล้ว ๕๕๕๕+ 
ค่อยๆเป็น ค่อยๆไปกันดีกว่าเนอะ (เหมือนสอนให้รู้จักรัก ต้องค่อยๆเจ็บ ค่อยๆจำ เฮ…)

เข้าเรื่องซะที !

Delegate เอาจริงๆแล้ว มันเหมือนกับเชือกยาวๆๆๆๆ ที่มีกล้วยแขวนอยู่

ลองนึกว่ามีลิง ที่เดินจากปลายเชือกด้านนึงไปอีกด้านนึง มันจะหยิบกินกล้วยตามลำดับกล้วยที่แขวนอยู่บนเชือก

นี่ล่ะครับ Delegate จบ … แถ่นแท๊นนน

เดี๋ยวๆๆ Delegate คือเชือกยาวๆๆๆ แล้วลิงกินกล้วยไปเกี่ยวกับแมวน้ำขายสลัดผักยังไง?

งั้นเอางี้ละกัน เพื่อให้เข้าใจมากขึ้น
ถ้าผมบอกว่า กล้วย = ฟังก์ชัน, ลิงเดิน = การสั่งรัน delegate

(แน่ะ เหมือนจะเข้าใจ แต่ยังไม่ยอมเข้าใจอีก งั้นจะอธิบายต่ออีกหน่อยก็ได้)

สมมติว่าเรามีตัวแปร Delegate อยู่

public CustomDelegate deli;

ตามที่ท่านเข้าใจว่า deli คือตัวแปรชนิด CustomDelegate

แล้ว CustomDelegate เนี่ย ไม่ใช่ Class และไม่ใช่ Enum แต่มันคือพระเอก AV ของเรา ~>Delegate นั่นเอง

ทีนี้ท่านก็คงจะแย้งว่า ไม่เห็นจะบอกเลย ว่า CustomDelegate คืออะไร แล้วจู่ๆ จะมาใช้ได้ยังไง

ถูกต้องแล้วครับ ! และนี่คือวิธีการประกาศ Delegate type: CustomDelegate

public delegate string CustomDelegate(int n);

ดูเผิน เหมือนเป็น Function signature แค่มีคำว่า “delegate” แปะไว้ด้านหน้า

แต่จริงๆแล้วบรรทัดนี้หมายควายว่า … 
ความ !

เจ้า Compiler ! จงสร้าง delegate ที่มีชื่อว่า CustomDelegate ให้ข้าหน่อย
และฟังก์ชันที่จะเอามาใส่ใน CustomDelegate ได้นั้น ต้องรับ int และ return เป็น string
แปลได้ความว่า
เจ้ามนุษย์!จงสร้างเชือกที่มีชื่อว่า CustomDelegate ให้ข้าหน่อย และกล้วยที่จะเอามาแขวนได้นั้น ต้องเป็นกล้วยแบบที่ยัดตัวเลขเข้าไป แล้วมันจะพ่นข้อความออกมา

เบรคนิดนึง เพื่อหยุดให้ทำความเข้าใจ 6 วินาที … … โอเค หมดเวลา
ตอนนี้หลายคนอาจจะกำลังคิดว่า

พูดไปสองไพเบี้ย ดูตัวอย่างเสีย เข้าใจนานแล้ววว

ก็ได้ งั้นมาดูตัวอย่างการใช้งานกันเถอะ

deli = (n)=>{ Console.WriteLine(“HELLO “ + n); return “NOTHING“; };

บรรทัดบนนี้ เป็นการ สร้าง Anonymous Function แล้วจับโยนเข้าไปใน deli ที่เป็น delegate ที่เราสร้าง (สังเกตุว่า Anonymous Function นี้ รับ int n ปริ้น Hello + n และ return string “NOTHING” ซึ่งตรงกันกับตอนที่เราสร้าง delegate)

และเราสามารถเติมกล้วยได้อีกหลายลูก ตามที่เราต้องการ เช่น

deli += (n)=>{ Console.WriteLine(“WORLD “ + n); return “NILL“; };
deli += (n)=>{ Console.WriteLine(“PEACE “ + n); return “NONE“; };
deli += (n)=>{ Console.WriteLine(“OUT “ + n); return “NOPE“; };

เอาล่ะ ตอนนี้เชือก deli ของเรา มีกล้วยอยู่ 4 ชิ้น 
ถ้าเราสั่งให้ลิงเดิน (สั่งให้ delegate ทำงาน) มันก็จะกินตามลำดับกล้วยที่เราแขวนไว้

วิธีรัน delegate ทำได้ง่ายๆแบบนี้

deli(8)

แค่เนี๊ยะ เราก็จะได้ผลลัพธ์ก็จะเป็น

HELLO 8
WORLD 8
PEACE 8
OUT 8

ง่ายดายมากกกกกก ใช่ไหมครับ

ผมเชื่อว่าใครที่อ่านมาถึงบรรทัดนี้ คงจะมีเวลาว่างมาก ที่ยอมทนอ่านมาได้ถึงเพียงนี้
ผมจะขอแนะนำหน่อย สาวๆหน้าร้าน BlueCup (S&P) ที่ Central World ตึก Office ชั้น 3 น่ารักสาดดดดดดดดดดดด เลิกอ่าน แล้วไปหาที่นั่งเหล่สาวกันได้แล้วสหายย!!!

ปล. Dig Deep into Delegate hell part 2 จะมาในอีกเร็วๆนี้ !
(ภายในวันที่ 2017–10–02)(เพื่อเตือนตัวเอง)(และให้คนอื่นเตือน)

มาแล้ว ! Part 2

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.