أساليب التوسيع (Visual Basic)

Visual Basic 2008 يقدم أساليب التوسيع, والتي تتيح للمطورين لإضافة وظيفة مخصصة لأنواع البيانات التي تم تعريفها مسبقاً بدون إنشاء نوع مشتق جديد. أساليب التوسيع تجعل من الممكن كتابة أسلوب التي يمكن استدعاؤها كما لو كان أسلوب مثيل من النوع الموجود.

ملاحظات

أسلوب التوسيع يمكن أن يكون فقط إجراء Sub أو إجراء Function. لا يمكن تعريف خاصية توسيع أو حقل أو حدث. يجب أن يتم تمييز كل أساليب التوسيع مع سمة التوسيع <Extension()>، من مساحة الاسم System.Runtime.CompilerServices.

أول معلمة في تعريف أسلوب التوسيع يحدد أي نوع بيانات الذي يمده الأسلوب. عند يتم تنفيذ أسلوب، المعلمة الأولى مرتبطه بمثيل من نوع البيانات الذي يستدعي الأسلوب.

المثال

الوصف

يحدد المثال التالي Print التوسيع String نوع البيانات. يستخدم الـأسلوب Console.WriteLine لعرض سلسلة. معلمة Print الأسلوب aString، يؤسس أن ذلك الأسلوب يمد String الفئة.

Imports System.Runtime.CompilerServices

Module StringExtensions

    <Extension()> 
    Public Sub Print(ByVal aString As String)
        Console.WriteLine(aString)
    End Sub

End Module

لاحظ أن تعريف أسلوب التوسيع يحدد مع سمة التوسيع <Extension()>. وضع علامة أمام الوحدة النمطية حيث يتم تعريف الأسلوب يعتبر اختياري ولكن كل أسلوب توسيع يجب أن يتم وضع علامة عليه. System.Runtime.CompilerServices يجب استيراد في ترتيب للوصول سمة الملحق.

يمكن أن يتم تعريف أساليب التوسيع فقط داخل الوحدات النمطية. بشكل عام، الوحدة النمطية حيث يتم تعريف أسلوب التوسيع ليس نفس الوحدة النمطية مثل التي تم استدعاؤه فيها. بدلاً من ذلك، الوحدة النمطية التي تحتوي على أسلوب التوسيع يتم استيرادها, إذا كان يحتاج الأمر لذلك, لإحضارها في النطاق. بعد الوحدة النمطية التي تحتوي على Print في نطاق، يمكن استدعاء الأسلوب كما لو كان أسلوب مثيل عادي الذي لا يأخذ وسائط، مثل ToUpper:

Module Class1

    Sub Main()

        Dim example As String = "Hello"
        ' Call to extension method Print.
        example.Print()

        ' Call to instance method ToUpper.
        example.ToUpper()
        example.ToUpper.Print()

    End Sub

End Module

المثال التالي, PrintAndPunctuate، هو أيضا توسيع لـ String، هذه المرة معرف مع معلمتين. المعلمة الـأولى, aString، يؤسس أن يمد أسلوب التوسيع String. الـمعلمة الثانية, punc، المقصود منها أن تكون سلسلة ذات علامات الترقيم التي يتم تمريرها كوسيطة عندما يتم استدعاء أسلوب. الـأسلوب يعرض سلسلة متبوعة بعلامات الترقيم.

<Extension()> 
Public Sub PrintAndPunctuate(ByVal aString As String, 
                             ByVal punc As String)
    Console.WriteLine(aString & punc)
End Sub

الـأسلوب يتم استدعاؤه عن طريق إرسال وسيطة سلسلة لـ punc: example.PrintAndPunctuate(".")

يظهر المثال التالي Print و PrintAndPunctuate معرفة و مستدعاه. System.Runtime.CompilerServices يتم استيراده في الوحدة النمطية التعريف لتمكين الوصول إلى سمة التوسيع.

الرمز

Imports System.Runtime.CompilerServices

Module StringExtensions

    <Extension()> 
    Public Sub Print(ByVal aString As String)
        Console.WriteLine(aString)
    End Sub

    <Extension()> 
    Public Sub PrintAndPunctuate(ByVal aString As String, 
                                 ByVal punc As String)
        Console.WriteLine(aString & punc)
    End Sub

End Module

بعد ذلك، أساليب التوسيع يتم إحضارها في نطاق تستدعى.

Imports ConsoleApplication2.StringExtensions
Module Module1

    Sub Main()

        Dim example As String = "Example string"
        example.Print()

        example = "Hello"
        example.PrintAndPunctuate(".")
        example.PrintAndPunctuate("!!!!")

    End Sub
End Module

التعليقات

كل ما هو مطلوب لتتمكن من تنفيذ هذه أو أساليب توسيع مشابهة هو أن تكون في نطاق. في حالة وحدة نمطية التي تحتوي على أسلوب توسيع موجودة في نطاق, يكون ذلك مرئياً في التحسس الذكي ثم يمكن استدعاؤه كما لو كان أسلوب مثيل عادي.

لاحظ أنه عندما يتم استدعاء الأساليب, لا يتم ارسال وسيطات لأول معلمة. معلمة الأولى، aString، في تعريف الأسلوب مرتبطة إلى example، مثيل String الذي يستدعي الأسلوب. سيستخدم المحول البرمجيexample كوسيطة مرسلة إلى أول معلمة.

الأنواع التي يمكن توسيعها

يمكنك تعريف أسلوب توسيع على معظم الأنواع التي يمكن تمثيلها في قائمة معلمة Visual Basic، بما في ذلك التالي:

  • الـفئات (أنواع المرجع)

  • بنيات (أنواع القيمة)

  • الواجهات

  • المفوضون

  • وسيطات ByRef و ByVal

  • معلمات الأسلوب العام

  • الصفائف

لأن أول معلمة تحدد نوع البيانات التي يمدها أسلوب التوسيع, فإنها مطلوبة ولا يمكن أن تكون اختيارية. لهذا السبب، Optional المعلمات و ParamArray المعلمات لا يمكن أن تكون المعلمة الأولى في قائمة المعلمات.

لا تعتبر أساليب التوسيع في وقت الربط المتأخر. في المثال التالي كشف anObject.PrintMe() يرفع MissingMemberException الاستثناء، ‏‏في نفس الاستثناء الذي ستشاهده إذا كان الثاني PrintMe تعريف أسلوب التوسيع تم حذفه.

Option Strict Off
Imports System.Runtime.CompilerServices

Module Module4

    Sub Main()
        Dim aString As String = "Initial value for aString"
        aString.PrintMe()

        Dim anObject As Object = "Initial value for anObject"
        ' The following statement causes a run-time error when Option
        ' Strict is off, and a compiler error when Option Strict is on.
        'anObject.PrintMe()
    End Sub

    <Extension()> 
    Public Sub PrintMe(ByVal str As String)
        Console.WriteLine(str)
    End Sub

    <Extension()> 
    Public Sub PrintMe(ByVal obj As Object)
        Console.WriteLine(obj)
    End Sub

End Module

أفضل الممارسات

أساليب التوسيع توفر طريقة ملائمة وفعالة لتوسيع نوع موجود. ومع ذلك، لاستخدامهم بنجاح, هناك بعض النقاط التي يجب أن تؤخذ بعين الاعتبار. يطبق هذه الاعتبارات بشكل رئيسي على الكتّاب مكتبات فئة ولكن قد يؤثر على أي يطبق يستخدم ملحق أساليب.

الأكثر عموماً، أساليب ملحق التي تضيفها إلى أنواع لا تملك أكثر عرضة من أساليب ملحق تمت الإضافة أنواع تتحكم أنت. يمكن حدوث عدد معين من الأشياء في الفئات التي لا تملكها التي يمكن أن تتداخل مع أساليب التوسيع.

  • في حالة وجود أي عضو مثيل قابل للوصول له الذي لديه توقيع يتوافق مع الوسيطات في الكشف المستدعي, دون عمليات تحويل تضييقي مطلوبة من وسيطة إلى معلمة, سيتم استخدام أسلوب المثيل في تفضيله لأي أسلوب توسيع. لذلك، إذا تمت إضافة أسلوب مثيل المناسب إلى فئة وقت ما, قد يصبح عضو توسيع موجودة الذيي تعتمد عليه غير قابل للوصول اليه.

  • لا يمكن أن يمنع كاتب أسلوب التوسيع المبرمجين الأخرين من كتابة أساليب توسيع متعارضة التي قد تكون لها الأسبقية على التوسيع الأصلي.

  • يمكنك تحسين الشدة عن طريق وضع أساليب التوسيع في مساحة الاسم الخاصة بهم. مستخدمين المكتبة الخاصة بك يمكنهم بعد ذلك تضمين مساحة الاسم أو استبعادهها أو اختيار بين مساحات الأسماء بشكل منفصل عن بقية المكتبة.

  • قد يكون أكثر أماناً توسيع واجهات عن توسيع فئات, خاصةً إذا لم تملك الواجهة أو الفئة. يؤثر تغيير في الواجهة على كل فئة التي تطبقها. لذلك، قد يكون الكاتب أقل احتمالاً لإضافة أو تغيير أساليب في واجهة. ومع ذلك، إذا قامت فئة بتنفيذ واجهتين والتي لديها أساليب توسيع مع نفس التوقيع,لن يكون أي منهما مرئياً.

  • توسيع النوع المحدد الأكثر امكانك توسيعه. في هيكل الأنواع، إذا قمت بتحديد نوع حيث العديد من الأنواع مشتقة منها, هناك طبقات لتقديم أساليب مثيل أو أساليب توسيع أخرى قد تتداخل مع الذي لديك.

أساليب التوسيع ، أساليب المثيل و الخصائص

عند يكون لأسلوب مثيل في نطاق توقيع الذي ينوافق مع وسائط كشف مستدعي, يتم اختيار أسلوب مثيل تفضيل على أي أسلوب توسيع. أسلوب مثيل له الأسبقية حتى إذا كان أسلوب التوسيع ذو تطابق أفضل. في المثال التالي ExampleClass يحتوي على أسلوب مثيل مسمى ExampleMethod يحتوي على معلمة واحدة من نوع Integer. أسلوب التوسيع ExampleMethod يوسع ExampleClass، ولديه معلمة واحدة من النوع Long.

Class ExampleClass
    ' Define an instance method named ExampleMethod.
    Public Sub ExampleMethod(ByVal m As Integer)
        Console.WriteLine("Instance method")
    End Sub
End Class

<Extension()> 
Sub ExampleMethod(ByVal ec As ExampleClass, 
                  ByVal n As Long)
    Console.WriteLine("Extension method")
End Sub

الاستدعاء أول لـ ExampleMethod في التعليمات البرمجية التالية يقوم باستدعاء أسلوب التوسيع لأن arg1 هو Long وهي متوافقة فقط مع Long المعلمة في أسلوب التوسيع. الـاستدعاء الثاني لـ ExampleMethod يحتوي Integer وسيطة arg2، و يقوم باستدعاء أسلوب مثيل.

Sub Main()
    Dim example As New ExampleClass
    Dim arg1 As Long = 10
    Dim arg2 As Integer = 5

    ' The following statement calls the extension method.
    example.exampleMethod(arg1)
    ' The following statement calls the instance method.
    example.exampleMethod(arg2)
End Sub

الآن اعكس أنواع البيانات للمعلمات في الأسلوبين:

Class ExampleClass
    ' Define an instance method named ExampleMethod.
    Public Sub ExampleMethod(ByVal m As Long)
        Console.WriteLine("Instance method")
    End Sub
End Class

<Extension()> 
Sub ExampleMethod(ByVal ec As ExampleClass, 
                  ByVal n As Integer)
    Console.WriteLine("Extension method")
End Sub

في هذه المرة التعليمات البرمجية في Main تقوم باستدعاء أسلوب مثيل كلا المرتين. وهذا لأن كلاهما arg1 و arg2 لديهما تحويل توسيعي لـ Long، و أسلوب مثيل له الأسبقية على أسلوب التوسيع في كلا الحالتين.

Sub Main()
    Dim example As New ExampleClass
    Dim arg1 As Long = 10
    Dim arg2 As Integer = 5

    ' The following statement calls the instance method.
    example.ExampleMethod(arg1)
    ' The following statement calls the instance method.
    example.ExampleMethod(arg2)
End Sub

لذلك، لا يمكن استبدال أسلوب التوسيع أسلوب مثيل موجود. ومع ذلك، عندما يكون أسلوب التوسيع له نفس الاسم كأسلوب مثيل ولكن لا تتعارض التواقيع, يمكن الوصول إلى كلا الأسلوبين. على سبيل المثال، إذا كانت فئة ExampleClass تحوي أسلوب باسم ExampleMethod التي لا تأخذ وسيطات ، أساليب توسيع بالاسم نفسه ولكن يتم السماح لتواقيع مختلفة, كما هو موضح في التعليمات البرمجية التالية.

Imports System.Runtime.CompilerServices

Module Module3

    Sub Main()
        Dim ex As New ExampleClass
        ' The following statement calls the extension method.
        ex.ExampleMethod("Extension method")
        ' The following statement calls the instance method.
        ex.ExampleMethod()
    End Sub

    Class ExampleClass
        ' Define an instance method named ExampleMethod.
        Public Sub ExampleMethod()
            Console.WriteLine("Instance method")
        End Sub
    End Class

    <Extension()> 
    Sub ExampleMethod(ByVal ec As ExampleClass, 
                  ByVal stringParameter As String)
        Console.WriteLine(stringParameter)
    End Sub

End Module

الإخراج من هذا التعليمات البرمجية كما يلي:

Extension method

Instance method

الموقف أبسط مع الخصائص: إذا كان أسلوب التوسيع له نفس اسم كخاصية فئة التي يمدها، أسلوب التوسيع غير مرئي ولا يمكن الوصول إليه.

أسبقية أسلوب التوسيع

عندما تكون أسلوبي توسيع التي تحتوي على تواقيع متطابقة في نطاق ويمكن الوصول إليها, سيتم استدعاء ذو الأسبقية. أسبقية أسلوب التوسيع يعيمد على آلية مستخدمة لتحويل أسلوب في نطاق. الـقائمة التالية تقوم بإظهار التسلسل الهرمي الأسبقي من الأعلى إلى الأقل.

  1. أساليب التوسيع معرفه داخل الوحدة النمطية الحالية.

  2. أساليب التوسيع المعرفة داخل أنواع البيانات في مساحة الاسم الحالية أو في أي من أصوله, مع مساحات الاسم التابعة التي تملك الأسبقية من مساحات الأسماء الأصل.

  3. أساليب التوسيع المعرفة داخل أي استيراد نوع في الملف الحالي.

  4. أساليب التوسيع المعرفة داخل أي استيراد مساحة اسم في الملف الحالي.

  5. أساليب التوسيع معرفة داخل أي استيراد نوع مستوى مشروع.

  6. أساليب التوسيع معرفة داخل أي استيراد مساحة اسم مستوى مشروع.

إذا لم تحل الأسبقية التباس, يمكنك استخدام اسم مؤهل بشكل كامل لتحديد الأسلوب الذي تستدعيه. إذا كان Print الأسلوب في المثال السابق تم تعريفة في الوحدة نمطية باسم StringExtensions، الاسم المؤهل بشكل كامل StringExtensions.Print(example) بدلاً من example.Print().

راجع أيضًا:

المهام

كيفية القيام بما يلي: تعريف المعلمات الاختيارية للإجراء

المرجع

System.Runtime.CompilerServices

كشف الوحدة النمطية

دعم Visual Basic و Visual C#‎

ExtensionAttribute

المبادئ

معلمات إجراء و وسيطات

المعلمات الإختيارية

صفائف المعلمة.

النطاق في Visual Basic