Overzicht: Dynamische objecten maken en gebruiken in Visual Basic

Dynamische objecten stellen leden beschikbaar, zoals eigenschappen en methoden tijdens runtime, in plaats van tijdens het compileren. Hiermee kunt u objecten maken om te werken met structuren die niet overeenkomen met een statisch type of een statische indeling. U kunt bijvoorbeeld een dynamisch object gebruiken om te verwijzen naar het HTML Document Object Model (DOM), dat elke combinatie van geldige HTML-opmaakelementen en -kenmerken kan bevatten. Omdat elk HTML-document uniek is, worden de leden voor een bepaald HTML-document tijdens de runtime bepaald. Een veelgebruikte methode om te verwijzen naar een kenmerk van een HTML-element is door de naam van het kenmerk door te geven aan de GetProperty methode van het element. Als u wilt verwijzen naar het id kenmerk van het HTML-element <div id="Div1">, verkrijgt u eerst een verwijzing naar het <div> element en gebruikt u divElement.GetProperty("id")vervolgens . Als u een dynamisch object gebruikt, kunt u verwijzen naar het id kenmerk als divElement.id.

Dynamische objecten bieden ook handige toegang tot dynamische talen, zoals IronPython en IronRuby. U kunt een dynamisch object gebruiken om te verwijzen naar een dynamisch script dat tijdens runtime wordt geïnterpreteerd.

U verwijst naar een dynamisch object met behulp van late binding. Je specificeert het type van een laat gebonden object als Object. Zie [Early and Late Binding] voor meer informatie.

U kunt aangepaste dynamische objecten maken met behulp van de klassen in de System.Dynamic naamruimte. U kunt bijvoorbeeld een ExpandoObject object maken en de leden van dat object opgeven tijdens runtime. U kunt ook uw eigen type maken waarmee de DynamicObject klasse wordt overgenomen. Vervolgens kunt u de leden van de DynamicObject klasse overschrijven om dynamische runtimefunctionaliteit te bieden.

Dit artikel bevat twee onafhankelijke handleidingen:

  • Maak een aangepast object waarmee de inhoud van een tekstbestand dynamisch wordt weergegeven als eigenschappen van een object.

  • Maak een project dat gebruikmaakt van een IronPython bibliotheek.

U kunt een van deze of beide doen, en als u beide doet, maakt de bestelling niet uit.

Vereisten

Notitie

Mogelijk worden op uw computer verschillende namen of locaties weergegeven voor sommige elementen van de Visual Studio-gebruikersinterface in de volgende instructies. De Visual Studio-editie die u hebt en de instellingen die u gebruikt, bepalen deze elementen. Zie Het IDE personaliseren voor meer informatie.

  • Installeer IronPython voor .NET voor het tweede scenario. Ga naar de downloadpagina om de nieuwste versie te verkrijgen.

Een aangepast dynamisch object maken

In het eerste overzicht wordt een aangepast dynamisch object gedefinieerd waarmee de inhoud van een tekstbestand wordt doorzocht. Met een dynamische eigenschap geeft u de tekst op die moet worden gezocht. Als u bijvoorbeeld code aanroept, retourneert dynamicFile.Sample de dynamische class een algemene lijst met tekenreeksen die alle regels uit het bestand bevatten die beginnen met "Sample". De zoekopdracht is niet hoofdlettergevoelig. De dynamische klasse ondersteunt ook twee optionele argumenten. Het eerste argument is een opsommingswaarde voor zoekopties die aangeeft dat de dynamische klasse moet zoeken naar overeenkomsten aan het begin van de regel, het einde van de regel of ergens in de regel. Het tweede argument geeft aan dat de dynamische klasse voorloop- en volgspaties van elke regel moet knippen voordat er wordt gezocht. Als u bijvoorbeeld code aanroept dynamicFile.Sample(StringSearchOption.Contains), zoekt de dynamische klasse ergens in een regel naar "Sample". Als de aanroepende code dynamicFile.Sample(StringSearchOption.StartsWith, false) specificeert, zoekt de dynamische klasse naar "Sample" aan het begin van elke regel en verwijdert geen voorloop- of volgspaties. Het standaardgedrag van de dynamische klasse is het zoeken naar een overeenkomst aan het begin van elke regel en het verwijderen van voorloop- en volgspaties.

Een aangepaste dynamische klasse maken

  1. Visual Studio starten.

  2. Selecteer Een nieuw project maken.

  3. In het dialoogvenster Een nieuw project maken, selecteer Visual Basic, selecteer Consoletoepassing en selecteer vervolgens Volgende.

  4. Voer in het dialoogvenster Configure your new project een naam in voor DynamicSample en selecteer vervolgens Volgende.

  5. Selecteer in het dialoogvenster Aanvullende informatie.NET 5.0 (huidig) voor het doelframework en selecteer vervolgens Maken.

    Het nieuwe project wordt gemaakt.

  6. Klik in Solution Explorer met de rechtermuisknop op het DynamicSample-project en selecteer Klasse toevoegen>. In het vak Naam typt u ReadOnlyFile en selecteert u Add.

    Er wordt een nieuw bestand toegevoegd dat de klasse ReadOnlyFile bevat.

  7. Voeg boven aan het bestand ReadOnlyFile.cs of ReadOnlyFile.vb de volgende code toe om de System.IO en System.Dynamic naamruimten te importeren.

    Imports System.IO
    Imports System.Dynamic
    
  8. Het aangepaste dynamische object gebruikt een enum om de zoekcriteria te bepalen. Voeg vóór de class-definitie de volgende enum-definitie toe.

    Public Enum StringSearchOption
        StartsWith
        Contains
        EndsWith
    End Enum
    
  9. Werk de klasse-instructie bij om de DynamicObject klasse over te nemen, zoals wordt weergegeven in het volgende codevoorbeeld.

    Public Class ReadOnlyFile
        Inherits DynamicObject
    
  10. Voeg de volgende code toe aan de ReadOnlyFile klasse om een privéveld voor het bestandspad en een constructor voor de ReadOnlyFile klasse te definiëren.

    ' 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
    
  11. Voeg de volgende methode GetPropertyValue toe aan de klasse ReadOnlyFile. De GetPropertyValue methode gebruikt, als invoer, zoekcriteria en retourneert de regels uit een tekstbestand dat overeenkomt met die zoekcriteria. De dynamische methoden die door de ReadOnlyFile klasse worden geleverd, roepen de GetPropertyValue methode aan om hun respectieve resultaten op te halen.

    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
    
  12. Voeg na de GetPropertyValue methode de volgende code toe om de TryGetMember methode van de DynamicObject klasse te overschrijven. De TryGetMember methode wordt aangeroepen wanneer een lid van een dynamische klasse wordt aangevraagd en er geen argumenten worden opgegeven. Het binder argument bevat informatie over het lid waarnaar wordt verwezen en het result argument verwijst naar het resultaat dat is geretourneerd voor het opgegeven lid. De TryGetMember methode retourneert een Booleaanse waarde die retourneert true als het aangevraagde lid bestaat; anders wordt deze geretourneerd 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
    
  13. Voeg na de TryGetMember methode de volgende code toe om de TryInvokeMember methode van de DynamicObject klasse te overschrijven. De TryInvokeMember methode wordt aangeroepen wanneer een lid van een dynamische klasse wordt aangevraagd met argumenten. Het binder argument bevat informatie over het lid waarnaar wordt verwezen en het result argument verwijst naar het resultaat dat is geretourneerd voor het opgegeven lid. Het args argument bevat een matrix van de argumenten die worden doorgegeven aan het lid. De TryInvokeMember methode retourneert een Booleaanse waarde die retourneert true als het aangevraagde lid bestaat; anders wordt deze geretourneerd false.

    In de aangepaste versie van de TryInvokeMember methode wordt verwacht dat het eerste argument een waarde is van de StringSearchOption enum die u in een vorige stap hebt gedefinieerd. De TryInvokeMember methode verwacht dat het tweede argument een Booleaanse waarde is. Als een of beide argumenten geldige waarden zijn, worden ze doorgegeven aan de GetPropertyValue methode om de resultaten op te halen.

    ' 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
    
  14. Sla het bestand op en sluit het bestand.

Een voorbeeldtekstbestand maken

  1. Klik in Solution Explorer met de rechtermuisknop op het DynamicSample-project en selecteer Nieuw item toevoegen>. Selecteer Algemeen in het deelvenster Geïnstalleerde sjablonen en selecteer vervolgens de sjabloon Tekstbestand. Laat de standaardnaam van TextFile1.txt in het vak Naam staan en klik vervolgens op Toevoegen. Er wordt een nieuw tekstbestand toegevoegd aan het project.

  2. Kopieer de volgende tekst naar het TextFile1.txt-bestand .

    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
    
  3. Sla het bestand op en sluit het bestand.

Een voorbeeldtoepassing maken die gebruikmaakt van het aangepaste dynamische object

  1. Dubbelklik in Solution Explorer op het Program.vb-bestand .

  2. Voeg de volgende code toe aan de Main procedure om een exemplaar van de ReadOnlyFile klasse voor het TextFile1.txt-bestand te maken. De code maakt gebruik van late binding om dynamische leden aan te roepen en regels met tekst op te halen die de tekenreeks "Customer" bevatten.

    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
    
  3. Sla het bestand op en druk op Ctrl+F5 om de toepassing te bouwen en uit te voeren.

Een dynamische taalbibliotheek aanroepen

In de volgende procedure wordt een project gemaakt dat toegang heeft tot een bibliotheek die is geschreven in de dynamische taal IronPython.

Een aangepaste dynamische klasse maken

  1. Selecteer in Visual Studio Bestand>Nieuw>Project.

  2. In het dialoogvenster Een nieuw project maken, selecteer Visual Basic, selecteer Consoleapplicatie, en selecteer vervolgens Volgende.

  3. Voer in de Configureer uw nieuwe project dialoog een DynamicIronPythonSample voor de projectnaam in en selecteer vervolgens Volgende.

  4. Selecteer in het dialoogvenster Aanvullende informatie.NET 5.0 (huidig) voor het doelframework en selecteer vervolgens Maken.

    Het nieuwe project wordt gemaakt.

  5. Installeer het IronPython NuGet-pakket.

  6. Bewerk het Program.vb bestand.

  7. Voeg boven aan het bestand de volgende code toe om de Microsoft.Scripting.Hosting en IronPython.Hosting naamruimten uit de IronPython-bibliotheken en de System.Linq naamruimte te importeren.

    Imports Microsoft.Scripting.Hosting
    Imports IronPython.Hosting
    Imports System.Linq
    
  8. Voeg in de Main-methode de volgende code toe om een nieuw Microsoft.Scripting.Hosting.ScriptRuntime object te maken om de IronPython-bibliotheken te hosten. Het ScriptRuntime object laadt de IronPython-bibliotheekmodule 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.")
    
  9. Nadat de code voor het laden van de random.py-module is uitgevoerd, voegt u de volgende code toe om een matrix met gehele getallen te maken. De matrix wordt doorgegeven aan de shuffle methode van de random.py-module, waarmee de waarden in de matrix willekeurig worden gesorteerd.

    ' 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
    
  10. Sla het bestand op en druk op Ctrl+F5 om de toepassing te bouwen en uit te voeren.

Zie ook