Aracılığıyla paylaş


Uzantı Yöntemleri (Visual Basic)

Genişletme yöntemleri, geliştiricilerin yeni bir türetilmiş tür oluşturmadan tanımlanan veri türlerine ilave işlevsellik eklemelerini sağlar.Genişletme yöntemleri, mevcut türün örnek bir yöntemi gibi çağrılabilen bir yöntem yazılmasına olanak tanır.

Açıklamalar

Bir uzantı yöntemi, yalnızca bir Sub yordamı veya bir Function yordamı olabilir.Uzantı, özellik, alan veya olay tanımlayamazsınız.Tüm uzantı yöntemleri, System.Runtime.CompilerServices ad alanından <Extension()> uzantı özniteliğiyle işaretlenmelidir.

Bir genişletme yöntemi tanımındaki ilk parametre, yöntemin hangi veri türünü genişlettiğini belirtir.Yöntem ilk çalıştırıldığında ilk parametre yöntemi çağıran veri türü örneğine bağlıdır.

Örnek

Tanımlama

Aşağıdaki örnek String veri türüne bir Print genişletmesi tanımlar.Yöntem bir dize görüntülemek için Console.WriteLine kullanır.Print yönteminin parametresi, aString, yöntemi String sınıfına genişletir.

Imports System.Runtime.CompilerServices

Module StringExtensions

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

End Module

Uzantı yöntemi tanımının <Extension()> uzantı özniteliğiyle işaretlendiğine dikkat edin.Yöntemin tanımlandığı modülün işaretlenmesi isteğe bağlıdır ancak her genişletme yöntemi işaretlenmelidir.Uzantı özniteliğine erişim sağlamak için System.Runtime.CompilerServices içe aktarılmalıdır.

Uzantı yöntemleri yalnızca modüllerde bildirilebilir.Genelde bir uzantı yönteminin tanımlandığı modül, çağrıldığı modülle aynı değildir.Bunun yerine, gerekiyorsa genişletme yöntemini içeren modül kapsama alınmak üzere içe aktarılır.Print içeren modül kapsama dahil olduktan sonra yöntem, ToUpper gibi herhangi bir bağımsız değişken almayan, sıradan bir örnek yöntemi gibi çağırılabilir:

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

Sonraki örnek, PrintAndPunctuate, ayrıca bir String genişletmesidir, bu kez iki parametre ile tanımlanmıştır.İlk parametre olan aString, genişletme yönteminin String genişletmesini sağlar.punc olan ikinci parametrenin, yöntem çağrıldığında bağımsız değişken olarak geçen bir noktalama işaretleri dizesi olması öngörülmüştür.Yöntem dizi ve sonrasındaki noktalama işaretlerini görüntüler.

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

Yöntem bir dize içinde punc: example.PrintAndPunctuate(".") için bağımsız değişken göndererek çağrılır

Aşağıdaki örnek, tanımlanan ve çağrılan Print ile PrintAndPunctuate gösterir.Uzantı özniteliğine erişim sağlamak için System.Runtime.CompilerServices tanım modülüne içe aktarılır.

Code

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

Sonra, genişletme yöntemleri kapsama alınır ve çağrılır.

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

Comments

Bunları veya benzer genişletme yöntemlerini çalıştırmak için tek gereken, kapsam içinde olmalarıdır.Genişletme yöntemi içeren bir modül kapsam dahilindeyse IntelliSense'te görünür duruma gelir ve normal bir örnek yöntem gibi çağrılabilir.

Yöntemler çağrıldığında, hiçbir bağımsız değişkenin ilk parametre için gönderilmediğine dikkat edin.Önceki yöntem tanımlarındaki aString parametresi, onları çağıran String örneği olan example öğesine bağlıdır.Derleyici ilk parametreye gönderilen bağımsız değişken olarak example kullanacaktır.

Nothing olarak ayarlanan bir nesne için bir genişletme yöntemi çağrılırsa genişletme yöntemi yürütülür.Bu sıradan örnek yöntemleri için geçerli değildir.Nothing öğesini uzantı yönteminde açıkça denetleyebilirsiniz.

Genişletilebilen Türler

Aşağıdakiler dahil olmak üzere bir Visual Basic parametre listesinde gösterilebilecek çoğu türde genişletme yöntemi tanımlayabilirsiniz:

  • Sınıflar (başvuru türleri)

  • Yapılar (değer türleri)

  • Arayüzler

  • Temsilciler

  • ByRef ve ByVal bağımsız değişkenleri

  • Genel yöntem parametreleri

  • Diziler

İlk parametre, genişletme yönteminin genişlettiği veri türünü belirttiğinden gereklidir ve isteğe bağlı olamaz.Bu nedenle Optional parametreleri ve ParamArray parametreleri parametre listesindeki ilk parametre olamaz.

Genişletme yöntemleri geç bağlama kapsamında değerlendirilmez.Aşağıdaki örnekte, anObject.PrintMe() deyimi bir MissingMemberException özel durumu oluşturur, bu özel durum ikinci PrintMe genişletme yöntemi tanımı silindiğinde de görülür.

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

En İyi Yöntemler

Genişletme yöntemleri mevcut türü genişletmek için kullanışlı ve güçlü bir yöntem sağlar.Ancak bunları başarılı bir şekilde kullanmak için göz önüne alınması gereken bazı noktalar vardır.Bu durumlar özellikle sınıf kitaplıklarını yazarları için geçerli olabilir ancak uzantı yöntemlerini kullanan tüm uygulamaları da ekleyebilir.

Genellikle sahibi olmadığınız türlere eklediğiniz genişletme yöntemleri, sahibi olduğunuz türlere eklenen genişletme yöntemlerinden daha savunmasızdır.Size ait olmayan sınıflarda uzantı yöntemlerinizi engelleyebilecek birçok durum gerçekleşebilir.

  • Çağrı deyimindeki bağımsız değişkenlerle uyumlu imzası olan bir erişilebilir örnek üye varsa, bağımsız değişkenden parametreye daraltma dönüşümü olmadan, herhangi bir genişletme yöntemi için örnek yöntem kullanılır.Bu nedenle uygun bir örnek yöntemi bir noktada bir sınıfa eklenirse, bağlı olduğunuz mevcut uzantı üyesi erişilemez duruma gelebilir.

  • Bir genişletme yönteminin yazarı diğer programcıların orijinal genişletmeden daha öncelikli olabilecek, çakışan genişletme yöntemleri yazmasını engelleyemez.

  • Uzantı adlarını kendi ad alanına yerleştirerek sağlamlığı artırabilirsiniz.Kitaplığınızı kullanan tüketiciler, bu durumda bir ad alanı ekleyebilir veya hariç tutabilirler veya kitaplığın geri kalan kısmından ayrı olarak ad alanları arasında seçim yapabilirler.

  • Sınıfları genişletmek yerine arabirimleri genişletmek özellikle arabirimin veya sınıfın sahibi siz değilseniz daha güvenli olabilir.Arabirimdeki bir değişiklik, uygulandığı her sınıfı etkiler.Bu nedenle yazarın bir arabirimdeki yöntemlerde ekleme veya değiştirme yapma olasılığı daha az olabilir.Ancak bir sınıf, aynı imzaya sahip genişletme yöntemleri olan iki arabirim uygularsa genişletme yöntemlerinden hiçbiri görünür duruma gelmez.

  • En belirgin türü genişletin.Tür hiyerarşisinde çok sayıda türün derlendiği bir tür seçerseniz, örnek yöntemlerine veya sizin yöntemlerinizle çakışabilecek genişletme yöntemlerine giriş için çok sayıda olasılık katmanı mevcuttur.

Genişletme Yöntemleri, Örnek Yöntemler ve Özellikler

Bir kapsam içi örnek yönteminde deyim çağırma bağımsız değişkenleriyle uyumlu olan bir imza olduğunda, örnek yöntemi diğer uzantı yöntemlerine tercih edilir.Genişletme yönteminin eşleşmesi daha iyi olsa bile, öncelik örnek yönteminindir.Aşağıdaki örnekte, ExampleClass öğesi, Integer türünde bir parametreyi içeren ExampleMethod adında örnek bir yöntemi içerir.Genişletme yöntemi ExampleMethod, ExampleClass öğesini genişletir ve Long türünde bir parametreye sahiptir.

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

Aşağıdaki kodda ExampleMethod için yapılan ilk çağrı genişletme yöntemini çağırır çünkü arg1Long anlamına gelir ve yalnızca genişletme yöntemindeki Long parametresi ile uyumludur.ExampleMethod için yapılan ikinci çağrı bir Integer bağımsız değişkeni, arg2, içerir ve örnek yöntemini çağırır.

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

Şimdi, parametrelerin veri türlerini iki yöntemle ters çevirin:

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

Bu sefer Main içindeki kod iki seferde de örnek yöntemini çağırır.Bunun nedeni arg1 ve arg2 öğelerinin Long için geniş dönüştürmeye sahip olması ve örnek yöntemin her iki durumda da uzantı yöntemini geçersiz kılmasıdır.

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

Bu nedenle bir uzantı yöntemi, mevcut örnek yönteminin yerine kullanılamaz.Ancak bir genişletme yöntemi örnek yöntemle aynı ada sahipse fakat imzalar çakışmıyorsa her iki yönteme de erişilebilir.Örneğin, ExampleClass sınıfı hiçbir bağımsız değişken almayan ExampleMethod adında bir yöntem içeriyorsa, aşağıdaki kodda gösterildiği şekilde aynı ada ancak farklı imzalara sahip genişletme yöntemlerine izin verilir.

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

Bu kodun çıktısı aşağıdaki gibidir:

Extension method

Instance method

Durum özellikler ile daha basittir: Genişletme yöntemi genişlettiği sınıfın bir özelliği ile aynı ada sahipse, genişletme yöntemi görünmez ve buna erişilemez.

Genişletme Yöntemini Önceliği

Aynı imzaya sahip iki uzantı yöntemi kapsam içinde ve erişilebilir olduğunda, daha yüksek önceliğe sahip olan çağrılır.Bir uzantı yönteminin önceliği, yöntemi kapsam içine almak için kullanılan mekanizmaya dayanır.Aşağıdaki liste en yüksekten en düşüğe öncelik hiyerarşisini gösterir.

  1. Geçerli modül içinde tanımlanan genişletme yöntemleri.

  2. Geçerli ad alanındaki veya üst öğelerinden birindeki veri türlerinde tanımlanan genişletme yöntemleri için alt öğe ad alanlarının üst öğe ad alanlarına karşı daha fazla önceliği vardır.

  3. Herhangi bir türde tanımlanan genişletme yöntemleri geçerli dosyaya içe aktarılır.

  4. Herhangi bir ad alanında tanımlanan genişletme yöntemleri geçerli dosyaya içe aktarılır.

  5. Herhangi bir proje düzeyi türündeki ad alanında tanımlanan genişletme yöntemleri içe aktarılır.

  6. Herhangi bir proje düzeyindeki ad alanında tanımlanan genişletme yöntemleri içe aktarılır.

Öncelik belirsizliği ortadan kaldırmazsa çağırdığınız yöntemi belirtmek için tam nitelikli adı kullanabilirsiniz.Önceki örnekte bulunan Print yöntemi StringExtensions adında bir modülde tanımlandıysa tam nitelikli ad example.Print() yerine StringExtensions.Print(example) şeklindedir.

Ayrıca bkz.

Başvuru

System.Runtime.CompilerServices

Genişletme Yöntemleri (C# Programlama Kılavuzu)

Module Deyimi

Öznitelikler (C# ve Visual Basic)

ExtensionAttribute

Kavramlar

Yordam Parametreleri ve Bağımsız Değişkenler (Visual Basic)

İsteğe Bağlı Parametreler (Visual Basic)

Parametre Dizileri (Visual Basic)

Visual Basic'de Kapsam