สำหรับเบื้องหลังของ LINQ นั้น เทคโนโลยีสำคัญอย่างหนึ่งก็คือ Extension Method นั่นเองครับ เพราะด้วย Extension Method ทำให้เราสามารถใช้ LINQ ได้ โดยที่ runtime ยังเป็น v2.0.50727 เหมือนเดิม ที่เป็นแบบนี้เพราะว่า Extension Method นั้นทำให้เราสามารถเพิ่ม behavior ให้กับ Type ของเราได้โดยไม่จำเป็นต้องมี source code เดิมครับ
สมมติผมต้องการเพิ่มความสามารถให้กับ String Type สำหรับงาน Web Application ถ้าเป็นเมื่อก่อนก็อาจจะสร้าง sealed class ขึ้นมาโดยให้มี static method ที่ต้องการ (เพื่อที่ว่าจะได้ไม่ต้อง new object เวลาใช้งาน) ลองดูตัวอย่างครับ
Public NotInheritable Class MyExtension
Public Shared Function ApplyStyle(ByVal s As String) As String
Return String.Format("<span style='FONT-WEIGHT: bold;font-family:Verdana;color:red;'>{0}</span>", s)
End Function
Public Shared Function WriteLine(ByVal s As String) As String
Return String.Format("{0:#,##0}
", s)
End Function
End Class
แต่ถ้าเราสร้าง Extension Method ใน VB.NET นั้น เราจำเป็นต้องสร้างใน Module ครับ (C# จะสร้างใน Static Class ได้เลย แต่ VB.NET ไม่มี Static Class ครับ คือไม่สามารถใส่ "shared" keyword หน้า Class) และก็ใส่ Extension Attribute ด้วยครับ ลองมาดูโค้ดกัน
Public Module MyExtension2
<System.Runtime.CompilerServices.Extension()> _
Public Function EXApplyStyle(ByVal s As String) As String
Return String.Format("<span style='color:Red;font-weight:bold;font-family:Verdana'>{0}</span>", s)
End Function
<System.Runtime.CompilerServices.Extension()>
Public Function EXWriteLine(ByVal s As String) As String
Return String.Format("{0:#,##0} <br />", s)
End Function
End Module
คราวนี้มาดูเวลาการใช้งานกันครับ
Partial Class ModuleDisbursement_DBItemTest
Inherits System.Web.UI.Page
Protected Sub form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles form1.Load
Dim str As String = "Hello world."
Response.Write(MyExtension.WriteLine(MyExtension.ApplyStyle(str)))
Response.Write(str.EXApplyStyle().EXWriteLine())
End Sub
End Class
Reponse.Write บรรทัดแรก ใช้ Static Method ส่วนบรรทัดที่สองใช้ Extension Method ครับ สังเกตุได้ว่าเมื่อเราใช้ Extension Method แล้วเราจะเห็นว่า String Type ของเรามี method เพิ่มขึ้นมาอีก 2 ตัวครับ สะดวกดีจริงๆเลย
ปล. จากการ search ใน google พบว่า
- มี developer คนหนึ่งต้องการเพิ่ม method ใน BitMap Type แต่ทำไม่ได้ เพราะเป็น Sealed Class ครับ บางคนแนะนำให้สร้าง BitMap Type ของตัวเอง (ซึ่งเสียเวลาและต้องตามไปแก้โค้ดอีกเยอะเลย) และก็มีคนแนะนำให้ใช้ Extension Method มาแก้ปัญหานี้ครับ
- Microsoft MVP ชาวต่างชาติคนหนึ่งเขียนใน blog ว่า Module นี่ไง Static Class ของ VB.NET
- Microsoft MVP อีกคนเขียนอีก blog ว่า อยากให้มี Static Class ใน VB10 เพราะว่า Module มันยังไม่ใช่ Static Class จริงๆ (เค้าอธิบายว่ามันไม่เหมือนกันเพราะ Reflection - อืมม ยังไม่ค่อยเข้าใจครับ)
เพิ่มเติมมีคุยกันเรื่องนี้ที่ greatfreinds ครับ
มีวิธีที่จะใช้ Extension method โดยไม่ผ่าน Module ไหมครับ