รู้จักกับ Generic Class

Generic class คือลักษณะของคลาสที่ define การทำงานไว้กว้างๆ สามารถนำไปใช้กับตัวแปร Type ใดก็ได้
เมื่อเวลาใช้งานจริง เราจะต้องมีการกำหนด Type ที่ต้องการเจาะจงลงไป แล้วผลที่ได้ก็จะเป็น Type นั้นทั้งหมด

ตัวอย่างเช่น คลาสหนึ่งใน BCL ของ .NET ชื่อ List(Of T) (syntax ใน c# คือ List<T>)
หน้าที่กว้างๆ ของ List ก็คือมันเป็น collection ที่อนุญาตให้เราใส่ object อะไรบางอย่างเข้าไป ลบออก หรือเรียงลำดับ object ใน list ได้เป็นต้น
แต่เราสามารถเอาพฤติกรรมดังกล่าวของ List มาใช้กับตัวแปรประเภทอะไรก็ได้เช่น
เราจะมี list ของ Integer ก็ได้, list ของ String ก็ได้, list ของ Date ก็ได้
ยกตัวอย่างในคลาส List จะมีเมธอดชื่อว่า Add อยู่ เมธอดนี้ถ้าว่าตาม signature แล้วมันรับ parameter หนึ่งตัว มีชนิดเป็น T
นั่นหมายความว่า หาก List นั้นถูกประกาศให้เป็น list ของ Integer เมธอดนี้ก็จะต้อง Add เฉพาะสิ่งที่เป็น Integer เข้าไป
หรือเมธอด Sort ซึ่งทำหน้าที่เรียง object ใน list ก็จะทำการเรียงในแบบ Integer
พูดไปอาจจะงง ดูตัวอย่างดีกว่า

Dim iList As New List(Of Integer)
iList.Add(3) ' Parameter ต้องเป็น Integer เท่านั้น
iList.Add(2)
iList.Sort() ' List ถูกเรียงลำดับในแบบ Integer นั่นคือ 2, 3
Dim iArray = iList.ToArray ' ผลลัพธ์เป็น Integer Array

Dim sList As New List(Of String)
sList.Add("03") ' Parameter ต้องเป็น String เท่านั้น
sList.Add("2")
sList.Sort() ' List ถูกเรียงลำดับในแบบ String นั่นคือ "03", "2"
Dim sArray = sList.ToArray ' ผลลัพธ์เป็น String Array

ตัวอย่างที่สองเป็นคลาสที่มีประโยชน์มากๆ อีกคลาสหนึ่งก็คือ Dictionary(Of TKey, TValue) (c# Dictionary<TKey, TValue>)
หน้าที่ของ dictionary คือ ใช้เก็บคู่ของ entry ว่า ถ้า key มีค่าเท่านี้ จะมี value ค่าเท่านี้
generic class นี้รับ Type parameter ถึงสองตัว ตัวหนึ่งบอก type ของ key อีกตัวบอก type ของ value

Dim postal As New Dictionary(Of String, String)
postal.Add("10", "Bangkok")
postal.Add("11", "Nontaburi")
Console.WriteLine(postal("10")) ' ผลลัพธ์จะได้ Bangkok {String}

Dim holiday As New Dictionary(Of String, Date)
holiday.Add("maghapuja", #2/9/2009#) ' มาฆบูชา วันที่เก้า เดือนสอง ปีสองพันเก้า
holiday.Add("visakhapuja", #5/8/2009#) ' วิสาขบูชา วันที่แปด เดือนห้า ปีสองพันเก้า
Console.WriteLine(holiday("maghapuja")) ' ผลลัพธ์จะได้ วันที่เก้า เดือนสอง ปีสองพันเก้า {Date}

Generic class นี้ช่วยให้เราเขียนโปรแกรมได้ Type Safe มากยิ่งขึ้น
อย่างถ้าเรากำหนดเป็น Dictionary(Of String, Date) แล้ว เราไม่มีทางที่จะใส่ Entry เป็นตัวแปรชนิดอื่นได้เลย
Intellisense ใน Visual Studio มันก็จะบอก และถ้าใส่ผิดก็จะ compile ไม่ผ่านด้วย

Generic นี้สามารถทำได้ทั้งในระดับคลาส หรือแค่ระดับเมธอดก็ได้
เช่น สมมติเราจะทำ generic method สำหรับรับ input เป็นตัวแปรสองตัว แล้วส่ง output ออกมาเป็น array ก็เขียนได้ดังนี้

Public Function TwoPieces(Of T)(ByVal item1 As T, ByVal item2 As T) As T()
    Return New T() {item1, item2}
End Function

และเวลาเรียกใช้งานก็คือ

Dim twoInteger = TwoPieces(5, 6)
Dim twoString = TwoPieces("x", "y")

ซึ่งถ้าอยู่ใน Visual Studio แล้วลองเอาเมาส์ไปชี้ที่ตัวแปร twoInteger ก็จะเห็นว่ามันเป็น Type Integer Array
ส่วนตัวแปร twoString ก็จะเป็น String Array

สุดท้ายนี้ขอฝากภาพ Joke แบบโปรแกรมเมอร์ๆ มาให้ดูกัน
ดูแล้วจะยิ่งเข้าใจมากขึ้นว่า Generic คืออะไร

A Cup Of T

3 Responses to “รู้จักกับ Generic Class”

  1. Nuttapat Khantasaard Says:

    แล้วตัวแปรที่เป็น structure สามารถนำมาใช้กับ List(T) ได้ไหมครับ
    ถ้าได้อยากรบกวนขอตัวอย่างหน่อยครับ

    • panya Says:

      ได้แน่นอนครับ อย่างเช่น List(Of Color)

  2. Nuttapat Khantasaard Says:

    จริงๆแล้วตอนนี้กำลังทำมินิโปรเจ็คต์อยู่น่ะครับ
    แล้วทำมาถึงจุดหนึ่งก็ต้องเลือกอย่างใดอย่างหนึ่ง
    ระหว่าง List(T), Array, ArrayList, Collection
    แต่ไม่เคยทราบมาก่อนว่า 4 อย่างนี้ แตกต่างกันอย่างไรบ้าง
    และแต่ละอย่างเหมาะกับงานแบบไหน ก็เลยจะหาข้อมูลเพิ่มเติมหน่อยน่ะครับ
    หรือถ้าคุณปัญญาจะกรุณาช่วยชี้แนะก็จะเป็นพระคุณอย่างยิ่งครับ


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: