Page cover image

Anonymous Method

พิชญ์ตะวัน จันทรัตน์ 650710571

🌷แนวคิดของ Anonymous Method ถูกแนะนำในยุค C#2.0 ในการใช้งาน Anonymous Method จะถูกสร้างขึ้นโดยใช้คีย์เวิร์ด delegate ซึ่ง Anonymous Method ✕ไม่จำเป็นต้องมี✕ ชื่อเมธอด และ ประเภทของค่าที่คืนกลับ ((𝑯𝒆𝒏𝒄𝒆 𝒘𝒆 𝒄𝒂𝒏 𝒔𝒂𝒚, 𝒕𝒉𝒂𝒕 𝒂𝒏 𝒂𝒏𝒐𝒏𝒚𝒎𝒐𝒖𝒔 𝒎𝒆𝒕𝒉𝒐𝒅 𝒉𝒂𝒔 𝒐𝒏𝒍𝒚 𝒂 𝒃𝒐𝒅𝒚 𝒘𝒊𝒕𝒉𝒐𝒖𝒕 𝒂 𝒏𝒂𝒎𝒆, 𝒐𝒑𝒕𝒊𝒐𝒏𝒂𝒍 𝒑𝒂𝒓𝒂𝒎𝒆𝒕𝒆𝒓𝒔, 𝒂𝒏𝒅 𝒓𝒆𝒕𝒖𝒓𝒏 𝒕𝒚𝒑𝒆.)) แต่ก็ยังสามารถทำงานได้เหมือนเมธอดทั่วไป และสามารถเขียนแทรกลงในเมธอดอื่นได้ภายในโปรแกรม ✓ข้อดีคือช่วยให้เราสามารถเขียนโค้ดในบรรทัดเดียวแทนที่จะต้องมีชื่ออย่างชัดเจน ทำให้ลดความซับซ้อนเมื่อเมธอดนั้นถูกเรียกใช้เพียงครั้งเดียว

delegate operator?

delegate ถูกพัฒนาขึ้นมาเพื่อสนับสนุนการเขียนโปรแกรมใน C# เป็นตัวแปรประเภท reference type คือประเภทข้อมูลที่ใช้ในการอ้างอิงถึงเมธอดหรือฟังก์ชันอื่นๆ แทนที่จะอ้างถึง object โดย delegate ทำหน้าที่เหมือน "ตัวชี้ฟังก์ชัน" (function pointer) ในภาษาโปรแกรมอื่น ((ใน C# delegate คือ pointer ของเมธอดนั่นเอง📌))

🗝️Key points about the anonymous method

  • Anonymous Method เรียกอีกอย่างว่า inline delegate

  • สามารถสร้างวัตถุตัวแทน (delegate object) ได้โดยไม่ต้องเขียน method แยกต่างหาก

  • A variable declared outside the anonymous method can be accessed inside the anonymous method. ตัวแปรที่ประกาศไว้ภายนอก anonymous method สามารถเข้าถึงได้ภายในเมธอด

  • A variable declared inside the anonymous method can’t be accessed outside the anonymous method. ตัวแปรที่ประกาศไว้ภายใน anonymous method ไม่สามารถเข้าถึงได้จากภายนอกเมธอด

ตัวอย่าง

//สร้าง delegate ชื่อ del สำหรับเมธอดที่รับ int สองค่าและคืนค่าเป็น int
delegate int del(int x, int y);

static void Main(string[] args)
{
    //สร้าง Anonymous Method โดยใช้ delegate keyword ไม่จำเป็นต้องมีชื่อเมธอด
    del d1 = delegate(int x, int y) 
    { 
        return x * y; 
    };

    //เรียกใช้ Anonymous Method ผ่าน delegate d1
    int z1 = d1(2, 3);
    
    Console.WriteLine(z1); //Output: 6 (ผลลัพธ์จาก x * y(2, 3))
}

ตัวอย่างที่ 1 เป็นการสร้าง anonymous method ในรูปแบบปกติ โดยมีการประกาศและใช้งานเมธอดที่ไม่มีชื่อผ่านการกำหนดให้กับ delegate

using System;
using System.Threading;

class AnonymouseMothod
{
    //สร้าง delegate ชื่อ MeDelegate ซึ่งไม่ได้รับพารามิเตอร์ใดๆ และคืนค่าเป็น void
    delegate void MeDelegate(); 

    static void Main(string[] args)
    {
        //basic anomymous method > สร้าง Anonymous Method โดยใช้คำว่า delegate 
        //โดยไม่มีการระบุพารามิเตอร์ (เพราะ MeDelegate ไม่ได้กำหนดพารามิเตอร์)
        MeDelegate de = delegate
        {
            Console.WriteLine("Anonymouse is invoked.");
        };
        de(); //เรียกใช้ Anonymous Method ผ่าน delegate de ทำให้ข้อความแสดงออกมาทางคอนโซล

        //basic anomymous method with thread
        //สร้าง Anonymous Method อีกครั้ง แต่อันนี้ใช้สำหรับทำงานร่วมกับ Thread
        Thread t = new Thread(new ThreadStart(delegate
        {
            Console.WriteLine("Anonymouse method in thread.");
        }));

        t.Start(); //เริ่มการทำงานของ thread ซึ่งทำให้ข้อความถูกพิมพ์ออกมาภายใน thread ใหม่
    }
}

ตัวอย่างที่ 2 เป็นการสร้าง anonymous method ทั้งในรูปแบบปกติและในกรณีที่ใช้กับการสร้าง thread โดยมีการเรียกใช้ผ่าน delegate และ thread ซึ่งจะเห็นว่า anonymous method ถูกใช้บ่อยๆ

ข้อดีของการใช้ Anonymous Method ทำให้สร้างฟังก์ชันแบบชั่วคราว (ไม่ต้องการชื่อ) ได้ง่ายๆ ภายในโค้ดโดยไม่ต้องประกาศแยกเป็นเมธอดใหม่😎

เปรียบเทียบกับภาษา Java

ใน Java เวอร์ชันก่อน Java 8 ไม่มี Anonymous Method แต่มีการใช้ Anonymous Class เพื่อกำหนดพฤติกรรมเฉพาะในที่เดียว ต่อมาใน Java 8 มีการเพิ่ม Lambda Expressions ทำให้การสร้างฟังก์ชันแบบไม่มีชื่อทำได้ง่ายขึ้น

  • Anonymous Classes ช่วยให้เขียนโค้ดได้กระชับขึ้น สามารถประกาศและสร้างอินสแตนซ์ของคลาสได้ในเวลาเดียวกัน Anonymous Classes เหมือนกับ Local Classes ต่างกันที่คลาสนี้ไม่มีชื่อ นิยมใช้เมื่อต้องการใช้ Local Classes เพียงครั้งเดียว

//ตัวอย่าง Anonymous Class ที่มีการสร้างฟังก์ชันแบบไม่มีชื่อ
Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("Anonymous Method in Java");
    }
};
new Thread(r).start();
  • Lambda Expressions ถึงแม้ว่า Anonymous Classes จะแสดงให้เห็นการนำคลาสไปใช้โดยไม่ต้องตั้งชื่อ ที่มักจะกระชับกว่าคลาสที่มีชื่อ แต่สำหรับคลาสที่มีเพียงเมธอดเดียวก็ยังดูเหมือนจะยังยุ่งยากเกินไป ดังนั้นจึงเกิดนิพจน์แลมบ์ดาที่ช่วยให้แสดงอินสแตนซ์ของคลาสที่มีเมธอดเดียวได้กระชับมากขึ้นอีก

//ตัวอย่าง Lambda Expression
Runnable r = () -> System.out.println("Lambda Expression in Java");
new Thread(r).start();

เปรียบเทียบกับภาษา C

ภาษา C ไม่มีฟังก์ชันแบบ Anonymous Method โดยตรงเหมือนใน C# หรือ Java ในการทำงานที่คล้ายกับ Anonymous Method ใน C# จะต้องใช้การประกาศฟังก์ชันทั่วไป และส่ง pointer ของฟังก์ชันผ่านฟังก์ชันอื่น

#include <stdio.h>

//ฟังก์ชันปกติที่ถูกส่งไปยังฟังก์ชันอื่น
void printMessage() {
    printf("Anonymous-like function in C\n");
}

void execute(void (*func)()) {
    func();
}

int main() {
    //ส่งฟังก์ชันปกติผ่าน function pointer
    execute(printMessage);
    return 0;
}

เปรียบเทียบกับภาษา Python

ในภาษา Python จะใช้ Lambda Expressions คือ anonymous functions ขนาดเล็ก สร้างจากคีย์เวิร์ด lambda ซึ่งทำงานคล้ายกับ Anonymous Method ใน C# และ Lambda Expressions ใน Java โดยที่ Lambda Function ใน Python จะถูกจำกัดให้มีเพียงนิพจน์เดียว

เช่น lambda a, b: a+b ฟังก์ชันนี้จะส่งคืนผลรวมของอาร์กิวเมนต์สองตัว

//ตัวอย่างการใช้นิพจน์ lambda เพื่อส่งคืนฟังก์ชัน

>>>def make_incrementor(n):
...    return lambda x: x + n
...
>>>f = make_incrementor(42)
>>>f(0)
42
>>>f(1)
43

ความแตกต่าง Anonymous Method กับ Lambda Expressions

คุณสมบัติ
Anonymous Method
Lambda Expressions

ไวยากรณ์

ใช้คำว่า delegate

ใช้ => เป็น lambda operator

ความกระชับ

ไวยากรณ์ยาวกว่า

สั้นกว่าและกระชับกว่า

การใช้ type inference

ไม่รองรับ

รองรับ (C# คาดเดาชนิดพารามิเตอร์ได้)

การใช้กับ ref หรือ out

รองรับ

ไม่รองรับ

การใช้งานที่นิยม

ใช้ในโค้ดเก่าหรือสถานการณ์พิเศษ

นิยมใช้ในโค้ดใหม่และ LINQ

สรุปการเปรียบเทียบ📑

คุณลักษณะ
C# (Anonymous Method)
Java (Lambda Expressions)
C (ไม่มีฟังก์ชัน Anonymous)
Python (Lambda Function)

แนวคิดหลัก

ฟังก์ชันแบบไม่มีชื่อ ใช้ delegate หรือ Lambda Expressions

Lambda Expression / Anonymous Class

ใช้ function pointer แทน

Lambda Expressions สำหรับนิพจน์เดียว

การใช้งานง่าย

ใช้งานง่าย, รองรับ closure

ใช้งานง่าย, รองรับ closure

ต้องสร้างฟังก์ชันแบบมีชื่อและใช้ function pointer

ใช้งานง่าย, รองรับ closure

การเขียนโค้ด

สั้นและกระชับ โดยเฉพาะ Lambda

สั้นและกระชับมาก

โค้ดยาวและซับซ้อนกว่า

สั้นและกระชับ

การรองรับ closure

รองรับ closure

รองรับ closure

ไม่มี

รองรับ closure

การใช้งานกับ Thread

ใช้งานง่ายผ่าน Thread

ใช้งานง่ายผ่าน Runnable

ใช้ thread library และ function pointer

ใช้งานง่ายผ่าน thread module

  • Video

  • Presentation (slides)

แหล่งที่มาอ้างอิง

เนื้อหา(แนวคิด, Key point)

GeeksforGeeks. (2019). Anonymous method in C#. GeeksforGeeks. https://www.geeksforgeeks.org/anonymous-method-in-c-sharp/

ScholarHat. (2024). C# anonymous method. ScholarHat. https://www.scholarhat.com/tutorial/csharp/c-sharp-anonymous-method

delegate operator

Microsoft. (2024). Delegate operator (C# reference). Microsoft Learn. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/delegate-operator

ตัวอย่าง 1

ScScholarHat. (2024). C# anonymous method. ScholarHat. https://www.scholarhat.com/tutorial/csharp/c-sharp-anonymous-method

ตัวอย่าง 2

MarcusCode. (2016). Delegates in C#. MarcusCode. https://marcuscode.com/lang/csharp/delegates

Anonymous Class and Lambda Expressions in Java

Oracle. (n.d.). Anonymous classes. Oracle Documentation. https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

Oracle. (n.d.). Lambda expressions. Oracle Documentation. https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Function Pointer in C

GeeksforGeeks. (2024). Function pointer in C. GeeksforGeeks. https://www.geeksforgeeks.org/function-pointer-in-c/

Lambda Expressions in Python

Python Software Foundation. (n.d.). Lambda expressions. Python Documentation. https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions

Last updated