Przewodnik: tworzenie i używanie obiektów dynamicznych w Visual Basic
Obiekty dynamiczne uwidaczniają elementy członkowskie, takie jak właściwości i metody w czasie wykonywania, a nie w czasie kompilacji. Dzięki temu można tworzyć obiekty do pracy ze strukturami, które nie są zgodne z typem statycznym ani formatem. Na przykład można użyć obiektu dynamicznego, aby odwołać się do modelu obiektów dokumentów HTML (DOM), który może zawierać dowolną kombinację prawidłowych elementów i atrybutów znaczników HTML. Ponieważ każdy dokument HTML jest unikatowy, elementy członkowskie określonego dokumentu HTML są określane w czasie wykonywania. Typową metodą przywołowania atrybutu elementu HTML jest przekazanie nazwy atrybutu do GetProperty
metody elementu. Aby odwołać się do id
atrybutu elementu <div id="Div1">
HTML, najpierw uzyskaj odwołanie do <div>
elementu, a następnie użyj polecenia divElement.GetProperty("id")
. Jeśli używasz obiektu dynamicznego, możesz odwołać się do atrybutu id
jako divElement.id
.
Obiekty dynamiczne zapewniają również wygodny dostęp do języków dynamicznych, takich jak IronPython i IronRuby. Za pomocą obiektu dynamicznego można odwoływać się do skryptu dynamicznego interpretowanego w czasie wykonywania.
Odwołujesz się do obiektu dynamicznego przy użyciu opóźnionego powiązania. Typ obiektu powiązanego z opóźnieniem określa się jako Object
. Aby uzyskać więcej informacji, zobacz [Wczesne i późne powiązanie.
Niestandardowe obiekty dynamiczne można tworzyć przy użyciu klas w System.Dynamic przestrzeni nazw. Można na przykład utworzyć element ExpandoObject i określić elementy członkowskie tego obiektu w czasie wykonywania. Możesz również utworzyć własny typ, który dziedziczy klasę DynamicObject . Następnie można zastąpić składowe DynamicObject klasy, aby zapewnić dynamiczne funkcje czasu wykonywania.
Ten artykuł zawiera dwa niezależne przewodniki:
Utwórz obiekt niestandardowy, który dynamicznie uwidacznia zawartość pliku tekstowego jako właściwości obiektu.
Utwórz projekt, który używa
IronPython
biblioteki.
Możesz wykonać jedną z tych lub obu tych czynności, a jeśli zrobisz oba te czynności, kolejność nie ma znaczenia.
Wymagania wstępne
- Program Visual Studio 2019 w wersji 16.9 lub nowszej z zainstalowanym pakietem roboczym Programowanie aplikacji klasycznych platformy .NET. Zestaw .NET 5 SDK jest instalowany automatycznie po wybraniu tego obciążenia.
Uwaga
Na komputerze w poniższych instrukcjach mogą być wyświetlane inne nazwy i lokalizacje niektórych elementów interfejsu użytkownika programu Visual Studio. Te elementy są określane przez numer wersji Visual Studio oraz twoje ustawienia. Aby uzyskać więcej informacji, zobacz Personalizowanie środowiska IDE.
- W drugim przewodniku zainstaluj program IronPython dla platformy .NET. Przejdź do strony Pobieranie, aby uzyskać najnowszą wersję.
Tworzenie niestandardowego obiektu dynamicznego
Pierwszy przewodnik definiuje niestandardowy obiekt dynamiczny, który przeszukuje zawartość pliku tekstowego. Właściwość dynamiczna określa tekst do wyszukania. Jeśli na przykład wywołanie kodu określa dynamicFile.Sample
, klasa dynamiczna zwraca ogólną listę ciągów, które zawierają wszystkie wiersze z pliku rozpoczynającego się od "Sample". Wyszukiwanie nie uwzględnia wielkości liter. Klasa dynamiczna obsługuje również dwa opcjonalne argumenty. Pierwszym argumentem jest wartość wyliczenia opcji wyszukiwania, która określa, że klasa dynamiczna powinna wyszukiwać dopasowania na początku wiersza, na końcu wiersza lub w dowolnym miejscu w wierszu. Drugi argument określa, że klasa dynamiczna powinna przycinać spacje wiodące i końcowe z każdego wiersza przed wyszukiwaniem. Jeśli na przykład wywołanie kodu określa , klasa dynamiczna wyszukuje dynamicFile.Sample(StringSearchOption.Contains)
ciąg "Sample" w dowolnym miejscu w wierszu. Jeśli wywołanie kodu określa , klasa dynamiczna wyszukuje dynamicFile.Sample(StringSearchOption.StartsWith, false)
ciąg "Sample" na początku każdego wiersza i nie usuwa spacji wiodących i końcowych. Domyślne zachowanie klasy dynamicznej polega na wyszukiwaniu dopasowania na początku każdego wiersza i usuwaniu spacji wiodących i końcowych.
Aby utworzyć niestandardową klasę dynamiczną
Uruchom program Visual Studio.
Wybierz pozycję Utwórz nowy projekt.
W oknie dialogowym Tworzenie nowego projektu wybierz pozycję Visual Basic, wybierz pozycję Aplikacja konsolowa, a następnie wybierz pozycję Dalej.
W oknie dialogowym Konfigurowanie nowego projektu wprowadź
DynamicSample
nazwę projektu, a następnie wybierz przycisk Dalej.W oknie dialogowym Dodatkowe informacje wybierz pozycję .NET 5.0 (bieżąca) dla platformy docelowej, a następnie wybierz pozycję Utwórz.
Zostanie utworzony nowy projekt.
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt DynamicSample i wybierz pozycję Dodaj>klasę. W polu Nazwa wpisz
ReadOnlyFile
, a następnie wybierz pozycję Dodaj.Dodawany jest nowy plik zawierający klasę ReadOnlyFile.
W górnej części pliku ReadOnlyFile.cs lub ReadOnlyFile.vb dodaj następujący kod, aby zaimportować System.IO przestrzenie nazw i System.Dynamic .
Imports System.IO Imports System.Dynamic
Niestandardowy obiekt dynamiczny używa wyliczenia do określenia kryteriów wyszukiwania. Przed instrukcją class dodaj następującą definicję wyliczenia.
Public Enum StringSearchOption StartsWith Contains EndsWith End Enum
Zaktualizuj instrukcję klasy, aby dziedziczyła klasę
DynamicObject
, jak pokazano w poniższym przykładzie kodu.Public Class ReadOnlyFile Inherits DynamicObject
Dodaj następujący kod do klasy,
ReadOnlyFile
aby zdefiniować pole prywatne dla ścieżki pliku i konstruktor dlaReadOnlyFile
klasy.' Store the path to the file and the initial line count value. Private p_filePath As String ' Public constructor. Verify that file exists and store the path in ' the private variable. Public Sub New(ByVal filePath As String) If Not File.Exists(filePath) Then Throw New Exception("File path does not exist.") End If p_filePath = filePath End Sub
Dodaj następującą metodę
GetPropertyValue
do klasyReadOnlyFile
. MetodaGetPropertyValue
przyjmuje jako dane wejściowe kryteria wyszukiwania i zwraca wiersze z pliku tekstowego zgodnego z kryteriami wyszukiwania. Metody dynamiczne dostarczane przez klasęReadOnlyFile
wywołają metodę ,GetPropertyValue
aby pobrać odpowiednie wyniki.Public Function GetPropertyValue(ByVal propertyName As String, Optional ByVal StringSearchOption As StringSearchOption = StringSearchOption.StartsWith, Optional ByVal trimSpaces As Boolean = True) As List(Of String) Dim sr As StreamReader = Nothing Dim results As New List(Of String) Dim line = "" Dim testLine = "" Try sr = New StreamReader(p_filePath) While Not sr.EndOfStream line = sr.ReadLine() ' Perform a case-insensitive search by using the specified search options. testLine = UCase(line) If trimSpaces Then testLine = Trim(testLine) Select Case StringSearchOption Case StringSearchOption.StartsWith If testLine.StartsWith(UCase(propertyName)) Then results.Add(line) Case StringSearchOption.Contains If testLine.Contains(UCase(propertyName)) Then results.Add(line) Case StringSearchOption.EndsWith If testLine.EndsWith(UCase(propertyName)) Then results.Add(line) End Select End While Catch ' Trap any exception that occurs in reading the file and return Nothing. results = Nothing Finally If sr IsNot Nothing Then sr.Close() End Try Return results End Function
Po metodzie
GetPropertyValue
dodaj następujący kod, aby zastąpić metodę TryGetMember DynamicObject klasy . Metoda TryGetMember jest wywoływana, gdy żądana jest składowa klasy dynamicznej i nie określono żadnych argumentów. Argumentbinder
zawiera informacje o przywoływanej składowej, aresult
argument odwołuje się do wyniku zwróconego dla określonego elementu członkowskiego. Metoda TryGetMember zwraca wartość logiczną, która zwracatrue
wartość, jeśli żądany element członkowski istnieje; w przeciwnym razie zwraca wartośćfalse
.' Implement the TryGetMember method of the DynamicObject class for dynamic member calls. Public Overrides Function TryGetMember(ByVal binder As GetMemberBinder, ByRef result As Object) As Boolean result = GetPropertyValue(binder.Name) Return If(result Is Nothing, False, True) End Function
Po metodzie
TryGetMember
dodaj następujący kod, aby zastąpić metodę TryInvokeMember DynamicObject klasy . Metoda TryInvokeMember jest wywoływana, gdy element członkowski klasy dynamicznej jest żądany z argumentami. Argumentbinder
zawiera informacje o przywoływanej składowej, aresult
argument odwołuje się do wyniku zwróconego dla określonego elementu członkowskiego. Argumentargs
zawiera tablicę argumentów przekazywanych do elementu członkowskiego. Metoda TryInvokeMember zwraca wartość logiczną, która zwracatrue
wartość, jeśli żądany element członkowski istnieje; w przeciwnym razie zwraca wartośćfalse
.Niestandardowa wersja
TryInvokeMember
metody oczekuje, że pierwszy argument będzie wartością zStringSearchOption
wyliczenia zdefiniowanego w poprzednim kroku. MetodaTryInvokeMember
oczekuje, że drugi argument będzie wartością logiczną. Jeśli jeden lub oba argumenty są prawidłowymi wartościami, są przekazywane doGetPropertyValue
metody w celu pobrania wyników.' Implement the TryInvokeMember method of the DynamicObject class for ' dynamic member calls that have arguments. Public Overrides Function TryInvokeMember(ByVal binder As InvokeMemberBinder, ByVal args() As Object, ByRef result As Object) As Boolean Dim StringSearchOption As StringSearchOption = StringSearchOption.StartsWith Dim trimSpaces = True Try If args.Length > 0 Then StringSearchOption = CType(args(0), StringSearchOption) Catch Throw New ArgumentException("StringSearchOption argument must be a StringSearchOption enum value.") End Try Try If args.Length > 1 Then trimSpaces = CType(args(1), Boolean) Catch Throw New ArgumentException("trimSpaces argument must be a Boolean value.") End Try result = GetPropertyValue(binder.Name, StringSearchOption, trimSpaces) Return If(result Is Nothing, False, True) End Function
Zapisz i zamknij plik.
Aby utworzyć przykładowy plik tekstowy
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt DynamicSample i wybierz pozycję Dodaj>nowy element. W okienku Zainstalowane szablony wybierz pozycję Ogólne, a następnie wybierz szablon Plik tekstowy. Pozostaw domyślną nazwę TextFile1.txt w polu Nazwa , a następnie kliknij przycisk Dodaj. Nowy plik tekstowy jest dodawany do projektu.
Skopiuj następujący tekst do pliku TextFile1.txt .
List of customers and suppliers Supplier: Lucerne Publishing (https://www.lucernepublishing.com/) Customer: Preston, Chris Customer: Hines, Patrick Customer: Cameron, Maria Supplier: Graphic Design Institute (https://www.graphicdesigninstitute.com/) Supplier: Fabrikam, Inc. (https://www.fabrikam.com/) Customer: Seubert, Roxanne Supplier: Proseware, Inc. (http://www.proseware.com/) Customer: Adolphi, Stephan Customer: Koch, Paul
Zapisz i zamknij plik.
Aby utworzyć przykładową aplikację korzystającą z niestandardowego obiektu dynamicznego
W Eksplorator rozwiązań kliknij dwukrotnie plik Program.vb.
Dodaj następujący kod do
Main
procedury, aby utworzyć wystąpienieReadOnlyFile
klasy dla pliku TextFile1.txt . Kod używa opóźnionego powiązania do wywoływania dynamicznych elementów członkowskich i pobierania wierszy tekstu zawierających ciąg "Klient".Dim rFile As Object = New ReadOnlyFile("..\..\..\TextFile1.txt") For Each line In rFile.Customer Console.WriteLine(line) Next Console.WriteLine("----------------------------") For Each line In rFile.Customer(StringSearchOption.Contains, True) Console.WriteLine(line) Next
Zapisz plik i naciśnij Ctrl+F5 , aby skompilować i uruchomić aplikację.
Wywoływanie biblioteki językowej dynamicznej
Poniższy przewodnik tworzy projekt, który uzyskuje dostęp do biblioteki napisanej w języku dynamicznym IronPython.
Aby utworzyć niestandardową klasę dynamiczną
W programie Visual Studio wybierz pozycje Plik>Nowy>Projekt.
W oknie dialogowym Tworzenie nowego projektu wybierz pozycję Visual Basic, wybierz pozycję Aplikacja konsolowa, a następnie wybierz pozycję Dalej.
W oknie dialogowym Konfigurowanie nowego projektu wprowadź
DynamicIronPythonSample
nazwę projektu, a następnie wybierz przycisk Dalej.W oknie dialogowym Dodatkowe informacje wybierz pozycję .NET 5.0 (bieżąca) dla platformy docelowej, a następnie wybierz pozycję Utwórz.
Zostanie utworzony nowy projekt.
Edytuj plik Program.vb.
W górnej części pliku dodaj następujący kod, aby zaimportować
Microsoft.Scripting.Hosting
przestrzenie nazw iIronPython.Hosting
z bibliotek IronPython iSystem.Linq
przestrzeni nazw.Imports Microsoft.Scripting.Hosting Imports IronPython.Hosting Imports System.Linq
W metodzie Main dodaj następujący kod, aby utworzyć nowy
Microsoft.Scripting.Hosting.ScriptRuntime
obiekt do hostowania bibliotek IronPython. ObiektScriptRuntime
ładuje moduł biblioteki IronPython random.py.' Set the current directory to the IronPython libraries. System.IO.Directory.SetCurrentDirectory( Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) & "\IronPython 2.7\Lib") ' Create an instance of the random.py IronPython library. Console.WriteLine("Loading random.py") Dim py = Python.CreateRuntime() Dim random As Object = py.UseFile("random.py") Console.WriteLine("random.py loaded.")
Po załadowaniu kodu modułu random.py dodaj następujący kod, aby utworzyć tablicę liczb całkowitych. Tablica jest przekazywana do
shuffle
metody modułu random.py, który losowo sortuje wartości w tablicy.' Initialize an enumerable set of integers. Dim items = Enumerable.Range(1, 7).ToArray() ' Randomly shuffle the array of integers by using IronPython. For i = 0 To 4 random.shuffle(items) For Each item In items Console.WriteLine(item) Next Console.WriteLine("-------------------") Next
Zapisz plik i naciśnij Ctrl+F5 , aby skompilować i uruchomić aplikację.