VB.Net Extension Methods

3. February 2010

توسعه و گسترش توابع و کلاسها در ویژوال بیسیک دات نت

VbDotNetExtensionMethods در هنگام استفاده از کلاسها در برنامه‌نویسی، ممکن است برخی مواقع نیاز به کارایی بیشتری از کلاس مورد نظر داشته باشیم. مثلا نیاز به یک تابع اضافه در کلاس داریم که کار به خصوصی که مورد انتظارمون هست رو انجام بده. برای این کار چند راه حل وجود دارد:

یک راه، تغییر سورس کلاس مورد نظر هست. در این روش کاملا مشخصه که باید به سورس این کلاس دسنرسی داشته باشیم، تابع دلخواه رو به سورس اضافه کنیم و این کلاس رو در دات نت دوباره کامپایل کنیم.

خوب، اگه به سورس کلاس دسترسی نداشته باشیم چی؟ و یا در یک تیم برنامه نویسی، اجازه تغییر سورس کلاس‌های نوشته شده توسط بخشهای دیگه رو نداشته باشیم، یا کلا این تابع مورد نظر ما اونقدر استفاده به خصوص و شخصی داره که نیازی به وارد کردن اون در ساختار اصلی کلاس نباشه. حالا باید چه کرد؟
اگر به این فکر می‌کنید که میشه کلاس جدیدی ساخت و از کلاس مورد نظر ارث برد و متدهای جدید رو به اون اضافه کرد، بیخیال بشید. چون از هر کلاسی که نمیشه ارث پذیری داشت. ممکنه جلوی این قابلیت در کل کلاس گرفته شده باشه (NotInheritable) و یا این محدودیت در مورد برخی توابع وجود داشته باشه. خیلی دردسر داره نه؟

یک راه معمول دیگه در برنامه‌نویسی استفاده از کلاس‌های کمکی هست که به صورت Shared در VB.Net ساخته میشه (همون static دز سی شارپ). به این کلاس‌ها معمولا اسم Helper یا Utility گفته میشه چون که نقش کمکی در کدنویسی دارند و ممکن است چندین بار در یک برنامه از اونها استفاده بشه.

برای مثال نیاز به کنترل کردن آدرس ای‌‍میل وارد شده از طرف کاربر سایت هست تا ببینیم این ای‌میل درست نوشته شده یا نه؟ برای این کار یک کلاس به اسم AppUtility ایجاد می‌کنیم و یک تابع به اسم CheckEmail در اون به صورت Shared می‌سازیم:

Public Class MyUtility

    Public Shared Function CheckEmail(ByVal email As String) As Boolean

        Dim regex = New Regex("^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$")
        Return regex.IsMatch(email)

    End Function

End Class

و برای استفاده از این تابع به صورت زیر می‌توان عمل کرد:

Dim inputEmail = EmailTextbox.Text
If MyUtility.CheckEmail(inputEmail) Then
    'Email is valid..
    SubscribeUser()
Else
    'Email is invalid
    Throw New Exception("Email is invalid")
End If

همونطور که می‌بینید نیازی به ساختن یک آبجکت جدید از کلاس MyUtility نیست چرا که به صورت Shared تعریف شده. در کلاس MyUtility هر تعدادی از این مدل توابع که نیاز دارید می‌توانید بنویسید و از آن هر چند بار که نیاز دارید در طول برنامه، استفاده کنید.


Extension Methods

از ورژن دات نت 3 به بعد، یک قابلیت جدید با عنوان Extension Methods در همین راستا اضافه شد که کار را بسیار راحت تر کرد. با استفاده از Extension Methods شما میتوانید به هر کلاسی قابلیت های جدید رو اضافه کنید بدون اینکه به سورس و حتی ساختار اون کلاس دسترسی داشته باشید و هیچ نیازی به دوباره کامپایل کردن کلاس مورد نظر هم نیست. در واقع شما تابع مورد نظر خودتون رو نوشته و اون رو با این تکنیک وصل میکنید به کلاس مورد نظر.

برای استفاده از اکستنشن متد در VB.Net ابتدا باید یک Module بسازید. سپس باید مشخص کنید که تابع جدید را به چه نوع کلاسی میخواهید اضافه کنید؛ هر کلاسی که بود، باید اولین مقدار پاس شونده به تابع از نوع این کلاس باشد. نمونه کد زیر را ببینید:

Imports System.Runtime.CompilerServices
Public Module MyExtenstionMethods

   <Extension()> _
    Function CheckEmail(ByVal email As String) As Boolean
        Dim regex = New Regex("^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$")
        Return regex.IsMatch(email)
    End Function

    <Extension()> _
    Function MathWork(ByVal Number1 As Integer, ByVal Number2 As Integer) As Decimal
        Return (Number1 * Number2)/((Number1 + Number2)^2/3)
    End Function

End Module

در این مثال دو تابع به صورت Extension Method ساخته شده. تابع اول به اسم CheckEmail یک تابع کمکی برای کلاس String هست. چرا؟ به اولین مقدار پاس داده شده به تابع دقت کنید. متغیر email از نوع string هست. نام انتخاب شده برای email مهم نیست. چیزی که مهمه اینه که تون این متغیر از توع کلاس String هست. پس این تابع به کلاس String اضافه میشود و میتوان از آن استفاده کرد:

extenstionmethods1
همونطور که در شکل میبینید، متغیر mystring از نوع String ساخته شده و امکان استفاده از تابع CheckEmail برای آن فراهم شده است. در واقع در تابع CheckEmail متغیر اول الان در واقع خود mystring می‌باشد.
و البته مشخص است که ویژوال استودیو در هنگام کدنویسی، توابع اضافه شده را هم به سیستم intellisense خودش اضافه کرده که کار را بسیار راحت میکند. به علامتی که برای توابع اکتنشن استفاده شده است دقت کنید.

تابع دوم هم برای کلاس Integer تعریف می‌کنیم تا یک عملیات ریاضی را بین دو عدد انجام دهد (زیاد روی فرمول نوشته شده فکر نکنید!).  برای همین متغیر اول باید از نوع Integer تعریف شود تا این تابع به صورت خودکار به کلاس Integer اضافه شود. به این تابع میخواهیم یک عدد دیگر هم بفرستیم تا بین 2 عدد این فرمول ریاضی، یک عدد جدید را محاسبه کرده و تحویل دهد. نحوه استفاده از این اکستنشن به صورت زیر هست:

Dim FirstNumber as Integer = 22
ResultTextbox.Text = FirstNumber.MathWork(45)

در این حالت متغیر اول پاس داده شده به اکستنشن، FirstNumber یعنی عدد 20 هست و متغیر دوم هم عدد 45 میباشد. دقت کنید که Extension Method نوشته شده همواره تعداد ورودی های آن از تعداد متغیرهایی که باید هنگام کدنویسی به آن پاس دهید یکی بیشتر هست. چون متغیر اول پاس داده شده، همون آبجکتی هست که این اکستنشن رو برای کلاسش نوشتیم.

مثالی که در ابتدا با روش Helper Class نوشته شده بود را میتوان به صورت زیر نوشت:

If EmailTextbox.Text.CheckEmail Then
    'Email is valid..
    SubscribeUser()
Else
    'Email is invalid
    Throw New Exception("Email is invalid")
End If

چند نکته بسیار مهم وجود داره که اگر رعایت نکنید،ممکن هست Extension Method های شما کار نکند و برای زمان زیادی سر کار باشید:

حتما از Public Module استفاده کنید. اگر کلمه Public رو فراموش کنید، Extension Method شما کار نخواهد کزد.

نکته بعدی اینکه Imports System.Runtime.CompilerServices فراموش نشود و برای هر تابعی که میخواهید نقش Extension را بازی کند از فیلتر <Extension> همونطور که در نمونه کد می‌بینید استفاده کنید.

و در نهایت، بعد از نوشتن Module همواره حواستون باشه که ابتدا این فایل رو کامپایک کرده باشید و بعدا به سراغ استفاده از اون در قسمتهای دیگه مد بروید. اگر این کار را نکنید، ویژوال استودیو توابع اکستنشن شما رو در intellisense نمیاره. برای کامپایل کردن در ویژوال استودیو از منو Build و بعد از اون Build class name استفاده کنید.

 

*این مطالب از خودم میباشد! اگر در اون مورد اشتباهی میبینید، ممنون میشم که اعلام کنید و استفاده از این مطلب آزاد هست و اگر دوست دارید با انصاف باشید، منبع رو هم ذکر کنید.


دسته بندی موضوعی: ASP.Net
برچسب ها: - - -

Comments

2/4/2010 3:56:28 PM #
agha mohamad reza,in axaye ghesmate tablighat ro che juri injuri kardi?
manzuram ine che juri ax mizari?
khode blogengine daratesho mishe taghiresh dad ya na shoma khodet joda ezafe kardi?
mishe masalan ghesmate linke doostan ro injuri tasviri kard?
mishe rahnamaeim koni?
ajaleie
mamnunam
me
2/4/2010 11:37:02 PM #
تبسم:
شما با ادمین تو بلاگ انجین لاگین کن بعدش در قسمت پلاگین ها، پلاگین textbox رو اضافه کن و موقع ادیت کردنش برو تو سورس و کد اچ تی ام ال عکس رو بنویس

Pingbacks & Trackbacks

  1. trackback from: mohand.es   (05 Feb 2010)

Add comment


(Will show your Gravatar icon)

biuquoteLTR
Loading



Web Analytics
Subscribe
Follow me