Extension Methods

พิมพ์มณี น้องดี 650710573

Extension method เป็นวิธีการเพิ่ม method ให้คลาสหรือโครงสร้างที่มีอยู่ โดยไม่ต้องทำการแก้ไขหรือสืบทอดจากคลาสนั้นโดยตรง เหมาะสำหรับกรณีที่ไม่สามารถหรือไม่ควรแก้ไขคลาสเดิม นอกจากนี้ extension method ยังเป็น static method ที่จะอยู่ภายใน static class และสามารถเรียกใช้งานได้เช่นเดียวกับ instance method ที่มีอยู่ในคลาสทั่วไปอีกด้วย

To declare an extension method

  1. extension method จะต้องถูกสร้างใน static class และจะถูกประกาศเป็น static method โดย static class นี้ต้องไม่เป็น nested class

  2. ระดับการเข้าถึงของ extension method จะต้องอยู่ในระดับต่ำกว่าหรือเท่ากับระดับการเข้าถึงของclass

  3. พารามิเตอร์ตัวแรกของ extension method จะต้องใช้ this คีย์เวิร์ดเพื่อระบุชนิดของออบเจ็กต์ที่ method จะทำงานด้วย

namespace ExtensionMethods
{
    public static class IntExtensions
     {
        // อธิบายข้อ 3 เมธอดนี้สามารถทำงานเป็น extension method สำหรับประเภทข้อมูล int
        public static bool IsGreaterThan(this int x, int y)
        {
            x += 100;
            return x > y;
        }
    }
}

To implement an extension method

  1. การเรียกใช้ extension method จำเป็นต้องเพิ่ม using directive เพื่ออ้างอิงถึง namespace

  2. การเรียก extension method สามารถทำได้เหมือนการใช้ instance ของ class ปกติ

using System;
using ExtensionMethods;

class Program
{
    static void Main(string[] args)
    {
        int i = 10;
        // อธิบายข้อ 2
        // การส่งพารามิเตอร์แรกไปยัง extension method โดย binding ตัวแปร i เป็นพารามิเตอร์ x ใน extension method
        bool result = i.IsGreaterThan(200); 
        Console.WriteLine(result);
    }
}
output

False

ตัวอย่าง Extension Method เพิ่มเติม

มีการสร้างคลาสทั้งหมด 3 คลาส ประกอบด้วยคลาส Person ซึ่งมี properties ได้แก่ Name, Age, และ UniName พร้อมเมธอด Greet() , คลาส PersonExtensions เป็น static คลาสสำหรับสร้าง extension methods ได้อก่ PersonAge() และ PersonUni() เป็น method ที่จะไปเพิ่มการความสามารถของคลาส Person และคลาส Program ใช้สำหรับสร้างออบเจกต์ Person และเรียกใช้งานเมธอดต่าง ๆ และจะสังเกตเห็นว่า extension method ก็ถูกเรียกใช้งานผ่านอินสแตนซ์ของคลาส person เช่นเดียวกับเมธอดของคลาส

 public class Person
    {
    public string Name { get; set; }
        
    public int Age { get; set; }
        
    public string UniName { get; set; }

    public Person(string name, int age, string uniName)
    {
        Name = name;
        Age = age;
        UniName = uniName;
    }
        
    public void Greet(){
        Console.WriteLine($"Sawadee krub! I'm {Name},");
    }
}
namespace Sample
{
    public static class PersonExtensions
    {
        public static void PersonAge(this Person person)
        {
            Console.WriteLine($"{person.Age} years old,");
        }
        
        public static void PersonUni(this Person person, string str)
        {
            Console.WriteLine($"and I study at {person.UniName} {str}.");
        }
    }
}
using System;
using Sample; 

public class Program
{
    public static void Main(string[] args)
    {
        Person person = new Person("Carlos", 20, "Silpakorn");
        person.Greet();  
        person.PersonAge();
        person.PersonUni("University");
    }
}
output
Sawadee krub! I'm Carlos,
20 years old,
and I study at Silpakorn University.

ประเด็นสำคัญ

  • binding parameter คือพารามิเตอร์ที่ใช้สำหรับผูก extension method เข้ากับคลาสหรือโครงสร้างที่มีอยู่ โดยพารามิเตอร์นี้จะไม่รับค่าใดๆ เมื่อมีการเรียกใช้งาน เนื่องจากมีหน้าที่ใช้สำหรับการผูกเท่านั้น ใน C# พารามิเตอร์นี้จะต้องอยู่ในตำแหน่งแรกเสมอ หากวางไว้ในตำแหน่งอื่นจะทำให้คอมไพเลอร์เกิดข้อผิดพลาด การสร้าง binding parameter สามารถมีได้แค่ตัวเดียวเท่านั้นโดยจะใช้คีย์เวิร์ด this ตามด้วยชื่อคลาสหรือโครงสร้างที่ต้องการเพิ่มเมธอดใหม่ และชื่อพารามิเตอร์ที่ใช้สำหรับผูกเมธอดนั้น

  • ถ้า extension method มีชื่อและ signature เหมือนกับเมธอดที่มีอยู่ในคลาสนั้น คอมไพเลอร์จะเลือกใช้เมธอดที่มีอยู่เดิมแทนการเรียกใช้ extension method

code : extension method ที่มีชื่อและ signature เหมือนกับ method ของคลาส
using System;
using Extension;

public class PrintStr
{
    public void printString()
    {
        Console.WriteLine("from class method");
    }
}
namespace Extension
{
public static class PrintStrExtensions
{
    // method ที่มีชื่อและ signature เหมือนกับ method ของคลาส
    public static void printString(this PrintStr s)
    {
        Console.WriteLine("from extension method");
    }
}
}
class Program
{
    static void Main(string[] args)
    {
        PrintStr s = new PrintStr();
        s.printString(); // output : from class method
    }
}
  • extension method ไม่สามารถใช้กับฟิลด์หรือ properties ได้

code : การใช้ extension method ร่ามกับ property
// โค้ดนี้เป็นบางส่วนของโค้ดตัวอย่างเพิ่มเติม เพื่อธิบายให้เข้าใจในหัวข้อนี้เท่านั้น!

public static void PersonAge(this Person person)
{
    // เข้าถึง property Age ผ่าน instance
    Console.WriteLine($"{person.Age} years old,");
}

ข้อดี/ ประโยชน์

  1. extension method คือการเพิ่มเมธอดใหม่ในคลาสที่มีอยู่แล้วโดยไม่ต้องใช้การสืบทอด

  2. extension method สามารถเพิ่มเมธอดใหม่ในคลาสที่มีอยู่โดยไม่ต้องแก้ไขโค้ดต้นฉบับของคลาสนั้น

  3. extension method ก็ยังสามารถทำงานกับคลาสที่ถูกปิด (sealed class) ได้

เปรียบเทียบกับภาษาอื่นๆ

  • Java ไม่รองรับ extension method เหมือน C# แต่สามารถเขียน static method แทนได้ วิธีนี้ช่วยให้สามารถเพิ่มความสามารถหรือเพิ่ม method ที่จำเป็นได้เช่นกัน แม้ว่าจะไม่มีการ binding ก็ตาม

class IntUtils {
    public static boolean isGreaterThan(int x, int y) {
        x += 100;
        return x > y;
    }
}

public class Main {
    public static void main(String[] args) {
        int i = 10;
        boolean result = IntUtils.isGreaterThan(i, 200);
        System.out.println(result);
    }
}
output

false

  • Python ไม่รองรับ extension method ที่เหมือน C# โดยตรง แต่สามารถทำสิ่งที่คล้ายคลึงกันได้โดยการเพิ่มฟังก์ชันเข้าไปในคลาสที่มีอยู่แล้วโดยใช้ setattr และนอกจากนี้ ใน python จะไม่มีการทำ binding อัตโนมัติเหมือนใน extension method ใน C#

class IntUtils :
    def __init__(self, x):
        self.x = x

def is_greater_than(self, y):
    x = self.x + 100 
    return x > y

# เพิ่มฟังก์ชันเข้าไปในคลาส setattr(obj, var, val)
setattr(IntUtils , 'is_greater_than', is_greater_than)

i = IntUtils(10)
result = i.is_greater_than(200) 
print(result) 
output

False

  • C ก็เป็นอีกภาษาไม่รองรับ extension method แบบ C# โดยตรง แต่สามารถเขียนฟังก์ชันแยกออกมาเพื่อเลียนแบบการทำงานได้ อย่างไรก็ตาม ฟังก์ชันเหล่านี้จะไม่มีการ binding พารามิเตอร์แบบที่เกิดขึ้นใน extension method ของ C#

#include <stdio.h>

int isGreaterThan(int x, int y) {
    x += 100; 
    return x > y;
}

int main() {
    int i = 10;
    int result = isGreaterThan(i, 200);
    printf("%s\n", result ? "True" : "False");
    return 0;
}
output

False

Presentation Video

References

IronPDF. (15 August, 2024). C# Extension Methods. Retrieved from https://ironpdf.com/blog/net-help/csharp-extension-methods/

ankita_saini. (13 Mar, 2024). Extension Method in C#. GeeksforGeeks.Retrieved from https://www.geeksforgeeks.org/extension-method-in-c-sharp/

Microsoft. (15 Mar, 2024). Extension Methods. Retrieved from https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods

Microsoft. (12 Mar, 2024). this keyword (C# Reference). Retrieved from https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/this

Microsoft. (3 Oct, 2024). How to: Implement and Call a Custom Extension Method. Retrieved from https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-implement-and-call-a-custom-extension-method

Kanth, S. (16 Feb, 2023). Static Class in C#. C# Corner. Retrieved from https://www.c-sharpcorner.com/UploadFile/74ce7b/static-class-in-C-Sharp/

George. (23 Dec, 2023). Extension Method in C#. C# Corner. Retrieved from https://www.c-sharpcorner.com/article/extension-method-in-c-sharp6/

Sarangi, S. (n.d.). C# concatenate strings. Naukri. Retrieved from https://www.naukri.com/code360/library/csharp-concatenate-strings

sanketnagare. (21 Aug, 2024). Static Method in Java. GeeksforGeeks. Retrieved from https://www.geeksforgeeks.org/static-method-in-java-with-examples/

W3Schools. (n.d.). C Functions Parameters. Retrieved from https://www.w3schools.com/c/c_functions_parameters.php

manjeet_04. (19 Jun, 2023). Python setattr() Method. GeeksforGeeks. Retrieved from https://www.geeksforgeeks.org/python-setattr-method/

Last updated