Udostępnij za pośrednictwem


Rozszerzenie metody (Visual Basic)

Rozszerzenie metody umożliwiają deweloperom dodać funkcje niestandardowe typy danych, które są już zdefiniowane bez tworzenia nowego typu pochodnego.Rozszerzenie metod należy napisać metodę, która może zostać wywołana, tak jakby był on metody instancji typu istniejących.

Uwagi

Metoda rozszerzenia może być tylko Sub procedury lub Function procedury.Nie można zdefiniować właściwość extension, pola lub zdarzenia.Wszystkie metody rozszerzenie musi być oznaczone atrybut rozszerzenie <Extension()> z System.Runtime.CompilerServices obszaru nazw.

Pierwszy parametr w definicji metody extension określa typ danych, który rozszerza metody.Po uruchomieniu metody pierwszy parametr jest związany z instancji typu danych, który wywołuje metodę.

Przykład

Bb384936.collapse_all(pl-pl,VS.110).gifOpis

Poniższy przykład definiuje Print rozszerzenie String typu danych.W metodzie Console.WriteLine do wyświetlenia, ciąg znaków.Parametr Print metody, aString, ustanawia, że metoda rozszerza String klasy.

Imports System.Runtime.CompilerServices

Module StringExtensions

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

End Module

Należy zauważyć, że definicja metody rozszerzenie jest oznaczony atrybutem rozszerzenie <Extension()>.Znakowanie moduł, w którym metoda jest zdefiniowana jest opcjonalne, ale każda metoda rozszerzenie muszą być oznakowane.System.Runtime.CompilerServicesmuszą być przywożone w celu uzyskania dostępu do atrybutu rozszerzenie.

Rozszerzenie metody mogą być deklarowane tylko w ramach modułów.Zazwyczaj moduł, w której zdefiniowano metodę rozszerzenia nie jest tym samym module jako jeden, w którym jest wywoływana.Zamiast tego modułu, który zawiera metodę rozszerzenia jest importowany, jeśli musi być, w celu dostosowania ich do zakresu.Po moduł, który zawiera Print jest w zakresie, można wywołać metody, tak jakby był on, że nie przyjmuje żadnych argumentów, takie jak metody instancji zwykłych 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

Następny przykład, PrintAndPunctuate, jest również rozszerzenie String, tym razem zdefiniowane z dwóch parametrów.Pierwszy parametr, aString, ustanawia, że metoda rozszerzenia rozszerza String.Drugi parametr, punc, ma być ciągiem znaków interpunkcyjnych jest przekazywana jako argument po wywołaniu metody.Metoda wyświetla ciąg znaków, a po nim za pomocą znaków interpunkcyjnych.

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

Metoda jest wywoływana przez wysyłanie w argumencie ciąg dla punc:example.PrintAndPunctuate(".")

W poniższym przykładzie Print i PrintAndPunctuate zdefiniowane i o nazwie.System.Runtime.CompilerServicesjest przywożone w module definicji w celu umożliwienia dostępu do atrybutu rozszerzenie.

Bb384936.collapse_all(pl-pl,VS.110).gifKod

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

Następnie metod rozszerzenia są doprowadzone do zakresu i o nazwie.

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

Bb384936.collapse_all(pl-pl,VS.110).gifKomentarze

Wszystkie wymagane będą mogli uruchamiać te lub podobne rozszerzenia metody się one w zakres.Jeśli moduł, który zawiera metodę rozszerzenia zakresu, jest widoczny w technologii IntelliSense i może zostać wywołana, tak jakby był on metody instancji zwykłych.

Należy zauważyć, że gdy wywoływane są metody, argument nie jest wysyłana w dla pierwszego parametru.Parametr aString w poprzednich metody definicje jest związany z example, wystąpienie String który je wywołuje.Kompilator będzie używać example jako argument wysłany do pierwszego parametru.

Jeśli dla obiektu, który jest ustawiona na wywoływana jest metoda rozszerzenie Nothing, metoda rozszerzenie.To nie ma zastosowania do instancji zwykłych metod.Można sprawdzić jawnie dla Nothing w metodzie rozszerzenie.

Typy, które mogą zostać rozszerzone

Można zdefiniować metodę rozszerzenia większość typów, które może być reprezentowany na liście parametrów języka Visual Basic, między innymi następujące:

  • Klasy (typy odwołań)

  • Budowle (typy wartości)

  • Interfejsy

  • Pełnomocnicy

  • Argumenty ByRef i ByVal

  • Parametry metody rodzajowe

  • Tablice

Ponieważ pierwszy parametr określa typ danych, który rozszerza metodę rozszerzenia, jest wymagana i nie może być opcjonalne.Z tego powodu Optional parametry i ParamArray parametrów nie może być pierwszy parametr na liście parametrów.

Rozszerzenie metody nie są uwzględniane w późnym wiązaniem.W poniższym przykładzie instrukcja anObject.PrintMe() podnosi MissingMemberException wyjątek, ten sam wyjątek będzie widoczne jeśli drugi PrintMe rozszerzenia definicji metody zostały usunięte.

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

Najważniejsze wskazówki

Rozszerzenie metody zapewniają wygodny, zaawansowany sposób rozszerzenia istniejącego typu.Aby użyć je pomyślnie, istnieją jednak wziąć pod uwagę na kilka kwestii.Te uwagi odnoszą się głównie do autorów bibliotek klas, ale mogą wpłynąć na dowolnej aplikacji, która używa metody rozszerzenie.

Zazwyczaj metody rozszerzenia, które można dodać do typów, które nie jest właścicielem są bardziej narażone niż metody rozszerzenie dodaje do typów, które można sterować.Liczba rzeczy mogą występować w klas, które nie jest właścicielem, które mogą zakłócać swoje metody rozszerzenie.

  • Jeśli każdy członek dostępne wystąpienia istnieje, która ma podpis, który jest zgodny z argumentów w instrukcji wywołującego z nie konwersji zawężającej wymagane od argumentu do parametru, metody instancji będzie używany uprzywilejowanych względem dowolnej metody rozszerzenie.W związku z tym jeśli metody instancji właściwe jest dodawane do klasy w pewnym momencie, istniejącego członka rozszerzenia, które korzystają z może stać się niedostępne.

  • Autor metodę rozszerzenia nie można zapobiec Pisanie metod rozszerzenie powodujące konflikt, które mogą mieć pierwszeństwo nad oryginalne rozszerzenie innych programistów.

  • Niezawodności można poprawić poprzez wprowadzenie metody rozszerzenie w ich własnych nazw.Konsumenci biblioteki można następnie obejmują obszar nazw lub wyklucz go lub zaznacz wśród obszarów nazw, niezależnie od pozostałej części biblioteki.

  • Może być bezpieczniejsze rozszerzenia interfejsów, niż jest rozszerzenie klasy, szczególnie, jeżeli nie posiadasz, interfejsu lub klasy.Zmiany w interfejsie wpływa na każdej klasy, która implementuje go.W związku z tym Autor może być mniej prawdopodobne dodać lub zmienić metody w interfejsie.Jednakże jeśli klasy implementuje dwa interfejsy, które mają rozszerzenie metody z takiego samego podpisu, ani metody rozszerzenie jest widoczny.

  • Rozszerzenie najbardziej określonego typu, który można.W hierarchii typów Jeśli zostanie wybrany typ, od których uzyskiwane są wielu innych typów, istnieją warstwy możliwości wprowadzenia metody instancji lub innych metod rozszerzenia, które mogą zakłócać zamierzonej.

Rozszerzenie metodami, metody instancji i właściwości

Gdy metody instancji w zakres ma podpis, który jest zgodny z argumentami wywołującego instrukcji, metody instancji jest wybierany uprzywilejowanych względem dowolnej metody rozszerzenie.Metody instancji ma pierwszeństwo, nawet jeśli metody rozszerzenie lepszego dopasowania.W poniższym przykładzie ExampleClass zawiera metodę instancji o nazwie ExampleMethod , ma jeden parametr typu Integer.Metoda rozszerzenie ExampleMethod rozszerza ExampleClass, i ma jeden parametr typu 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

Pierwsze wywołanie ExampleMethod w poniższy kod wywołuje metodę rozszerzenia, ponieważ arg1 jest Long i jest zgodny tylko z Long parametr w metodzie rozszerzenie.Drugie wywołanie ExampleMethod ma Integer argument, arg2, i wywołuje metodę instancji.

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

Teraz można odwrócić typy danych parametrów w dwóch metod:

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

Tym razem z kodem w Main wywołuje metodę instancji obu tych sytuacjach.Wynika to z obu arg1 i arg2 mają poszerzanie konwersji do Long, oraz metodę instancji mają pierwszeństwo przed metodę rozszerzenia w obu przypadkach.

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

Dlatego metodę rozszerzenia nie może zastąpić istniejące metody instancji.Jednakże gdy metoda rozszerzenie ma taką samą nazwę jak metody instancji, ale podpisy nie będą w konflikcie, obie metody są dostępne.Na przykład jeśli klasy ExampleClass zawiera metodę o nazwie ExampleMethod , które przekieruje nie argumentów, metody rozszerzenie o tej samej nazwie, ale różnych podpisów są dozwolone, jak pokazano w poniższym kodzie.

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

Dane wyjściowe z tego kodu, jest następująca:

Extension method

Instance method

Sytuacja jest prostsze właściwości: Jeśli metoda rozszerzenie ma taką samą nazwę jak właściwości klasy rozszerza, metoda rozszerzenie nie jest widoczny i nie jest dostępny.

Rozszerzenie metoda priorytet

W przypadku zakresu i dostępne dwie metody rozszerzenie, które mają identyczne podpisów zostanie wywołany, jeden o wyższym priorytecie.Pierwszeństwo metodę rozszerzenia opiera się na mechanizm zastosowany w celu dostosowania metody do zakresu.Na poniższej liście przedstawiono hierarchii pierwszeństwo, od najwyższego do najniższego.

  1. Rozszerzenie metod zdefiniowanych wewnątrz bieżącego modułu.

  2. Rozszerzenie zdefiniowane metody wewnątrz danych typów w bieżącym obszarze nazw lub w jednym z jego rodziców z przestrzeniami nazw dzieci mające wyższy priorytet niż nadrzędnego obszarów nazw.

  3. Rozszerzenie metod zdefiniowanych wewnątrz przywozu dowolnego typu w bieżącym pliku.

  4. Rozszerzenie metod zdefiniowanych wewnątrz żadnego przywozu obszaru nazw w bieżącym pliku.

  5. Rozszerzenie metod zdefiniowanych wewnątrz przywozu dowolnego typu na poziomie projektu.

  6. Rozszerzenie metod zdefiniowanych wewnątrz żadnego przywozu nazw na poziomie projektu.

Jeśli pierwszeństwo nie rozwiąże niejednoznaczności, można użyć w pełni kwalifikowana nazwa Aby określić metodę, który wywołujesz.Jeśli Print Metoda wcześniejszego przykładu jest zdefiniowany w module o nazwie StringExtensions, jest w pełni kwalifikowana nazwa StringExtensions.Print(example) zamiast example.Print().

Zobacz też

Informacje

System.Runtime.CompilerServices

Moduł instrukcji

Atrybuty (C# i Visual Basic)

ExtensionAttribute

Koncepcje

Parametry procedury i argumenty (Visual Basic)

Parametry opcjonalne (Visual Basic)

Tablic parametrów (Visual Basic)

Zakres w języku Visual Basic