วันอังคารที่ ๒๘ กรกฎาคม พ.ศ. ๒๕๕๒

ลองสร้าง Extension Method ใน VB9

ถ้าพูดถึง Visual Studio 2008 แล้ว พระเอกที่มีคนกล่าวขวัญถึงมากที่สุดไม่น่าจะมี feature ไหนเกิน LINQ ไปได้ครับ หลายๆคนคงได้นำ LINQ ไปใช้ในงานจริงกันบ้างแล้ว ส่วนตัวผมเองตอนที่ VS2008 ยังอยู่ในช่วง Beta และ CTP ก็มีคนพูดถึง LINQ ให้ฟังหลายคน แต่ไม่ค่อยได้สนใจครับ แต่พอมาลองใช้งานดูแล้วต้องบอกว่าเยี่ยมมากครับ

สำหรับเบื้องหลังของ 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 พบว่า

  1. มี developer คนหนึ่งต้องการเพิ่ม method ใน BitMap Type แต่ทำไม่ได้ เพราะเป็น Sealed Class ครับ บางคนแนะนำให้สร้าง BitMap Type ของตัวเอง (ซึ่งเสียเวลาและต้องตามไปแก้โค้ดอีกเยอะเลย) และก็มีคนแนะนำให้ใช้ Extension Method มาแก้ปัญหานี้ครับ

  2. Microsoft MVP ชาวต่างชาติคนหนึ่งเขียนใน blog ว่า Module นี่ไง Static Class ของ VB.NET

  3. Microsoft MVP อีกคนเขียนอีก blog ว่า อยากให้มี Static Class ใน VB10 เพราะว่า Module มันยังไม่ใช่ Static Class จริงๆ (เค้าอธิบายว่ามันไม่เหมือนกันเพราะ Reflection - อืมม ยังไม่ค่อยเข้าใจครับ)



เพิ่มเติมมีคุยกันเรื่องนี้ที่ greatfreinds ครับ
มีวิธีที่จะใช้ Extension method โดยไม่ผ่าน Module ไหมครับ

ไม่มีความคิดเห็น: