Wskazówki: Tworzenie obiektów dynamicznych i posługiwanie się nimi (C# i Visual Basic)

Obiekty dynamiczne narazić członków, właściwości i metod w czasie wykonywania, zamiast w w czasie kompilacji.Dzięki temu można tworzyć obiekty do pracy z struktur, które nie pasują do typu statycznego lub format.Na przykład można użyć dynamiczny obiekt, aby odwołać się za HTML dokumentu Object Model (DOM), który może zawierać dowolną kombinację ważne elementy znaczników HTML i atrybuty.Każdy dokument HTML jest unikatowy, członków w danym dokumencie HTML są określane w czasie wykonywania.Popularną metodą odniesienia atrybut HTML element jest przekazanie nazwa atrybutu do GetProperty metoda elementu.Aby odwołać się do id elementu HTML <div id="Div1">, najpierw uzyskać odwołania do <div> element, a następnie użyj divElement.GetProperty("id").Jeśli używasz obiektu dynamicznego, można odwoływać się do id atrybut jako divElement.id.

Obiekty dynamiczne jest również zapewniają wygodny dostęp do dynamicznych języków takich jak Boo i IronRuby.Aby odwołać się do dynamicznego skrypt, który jest interpretowany w czasie wykonywania, można użyć obiektu dynamicznego.

Dynamiczny obiekt odwołać się za pomocą późnym wiązaniem.W C#, możesz określić typ obiektu z późnym wiązaniem jako dynamic.W Visual Basic, należy określić typ obiektu z późnym wiązaniem jako Object.Aby uzyskać więcej informacji, zobacz dynamic (odwołanie w C#) i Wczesne i późne wiązania (Visual Basic).

Można utworzyć niestandardowe obiekty dynamiczne przy użyciu klas w System.Dynamic obszaru nazw.Na przykład można utworzyć ExpandoObject i określić członków tego obiektu w czasie wykonywania.Można również utworzyć własny typ, który dziedziczy DynamicObject klasy.Następnie można zastąpić członków DynamicObject klasy do wykonywania dynamicznych funkcjonalność.

W tym instruktażu będzie wykonywać następujące zadania:

  • Utwórz obiekt niestandardowy, który dynamicznie udostępnia zawartość pliku tekstowego jako właściwości obiektu.

  • Utwórz projekt, który IronPython biblioteki.

Wymagania wstępne

Należy Boo 2.6.1 4.0 .NET do przeprowadzenia tego instruktażu.Można pobrać Boo 2.6.1 dla .NET w wersji 4.0 z CodePlex.

[!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 Dostosowywanie ustawień środowiska deweloperskiego w Visual Studio.

Tworzenie dynamicznych obiektów niestandardowych

Pierwszy projekt, które są tworzone w tym instruktażu definiuje niestandardowy obiekt dynamiczny, który przeszukuje zawartość pliku tekstowego.Tekst do wyszukania jest określona nazwa właściwości dynamicznej.Określa, na przykład, jeśli wywołanie kodu dynamicFile.Sample, klasy dynamicznej zwraca ogólna lista ciągów, zawierający wszystkie wiersze z pliku, rozpoczynające się od ciągu "Próbki".Wyszukiwanie jest rozróżniana wielkość liter.Dynamiczne klasy obsługuje również dwóch argumentów opcjonalnych.Pierwszy argument jest wartość wyliczenia opcja wyszukiwania, który określa klasy dynamicznej należy szukać odpowiedników na początku wiersza, a koniec linii lub w dowolnym miejscu wiersza.Drugi argument określa, że klasy dynamicznej należy przyciąć spacje początkowe i końcowe z każdego wiersza przed wyszukiwaniem.Określa, na przykład, jeśli wywołanie kodu dynamicFile.Sample(StringSearchOption.Contains), klasy dynamicznej wyszukuje "Przykładowe" gdziekolwiek w linii.Określa, czy wywołanie kodu dynamicFile.Sample(StringSearchOption.StartsWith, false), klasy dynamicznej wyszukuje "Przykładowe" na początku każdego wiersza, a nie usuwa spacje początkowe i końcowe.Domyślne zachowanie dynamiczne klasy jest, aby wyszukać na początku każdej linii i usunąć spacje początkowe i końcowe.

Aby utworzyć niestandardowe klasy dynamicznej

  1. Start Visual Studio.

  2. Na pliku menu, wskaż Nowa , a następnie kliknij przycisk Projekt.

  3. W Nowy projekt okno dialogowe, w Typów projektu w okienka, upewnij się, że Windows jest zaznaczone.Wybierz Console Application w Szablony okienko.W Nazwa wpisz DynamicSample, a następnie kliknij przycisk OK.Tworzenia nowego projektu.

  4. Kliknij prawym przyciskiem myszy projekt DynamicSample i wskaż Dodaj, a następnie kliknij przycisk klasy.W Nazwa wpisz ReadOnlyFile, a następnie kliknij przycisk OK.Nowy plik zostanie dodany, który zawiera klasy ReadOnlyFile.

  5. Na początku pliku ReadOnlyFile.cs lub ReadOnlyFile.vb, Dodaj następujący kod, aby zaimportować System.IO i System.Dynamic obszarów nazw.

    Imports System.IO
    Imports System.Dynamic
    
    using System.IO;
    using System.Dynamic;
    
  6. Dynamiczny obiekt niestandardowy używa wyliczenia, aby określić kryteria wyszukiwania.Przed instrukcją klasy należy dodać następującą definicję enum.

    Public Enum StringSearchOption
        StartsWith
        Contains
        EndsWith
    End Enum
    
    public enum StringSearchOption
    {
        StartsWith,
        Contains,
        EndsWith
    }
    
  7. Klasa instrukcja Update do dziedziczą DynamicObject klasy, jak pokazano w poniższym przykładzie kodu.

    Public Class ReadOnlyFile
        Inherits DynamicObject
    
    class ReadOnlyFile : DynamicObject
    
  8. Dodaj następujący kod do ReadOnlyFile klasy, aby zdefiniować pole private dla ścieżki pliku oraz konstruktor dla ReadOnlyFile 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
    
    // Store the path to the file and the initial line count value. 
    private string p_filePath;
    
    // Public constructor. Verify that file exists and store the path in  
    // the private variable. 
    public ReadOnlyFile(string filePath)
    {
        if (!File.Exists(filePath))
        {
            throw new Exception("File path does not exist.");
        }
    
        p_filePath = filePath;
    }
    
  9. Dodaj następujący GetPropertyValue metoda ReadOnlyFile klasy.GetPropertyValue Metoda przyjmuje jako dane wejściowe, kryteria wyszukiwania i zwraca wartość wierszy tekstu pliku pasujących, że kryteria wyszukiwania.Dynamiczne metod dostarczonych przez ReadOnlyFile wywołanie klasy GetPropertyValue metoda pobierania ich odpowiednich wyników.

    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
    
    public List<string> GetPropertyValue(string propertyName,
                                         StringSearchOption StringSearchOption = StringSearchOption.StartsWith,
                                         bool trimSpaces = true) 
    {
        StreamReader sr = null;
        List<string> results = new List<string>();
        string line = "";
        string testLine = "";
    
        try
        {
            sr = new StreamReader(p_filePath);
    
            while (!sr.EndOfStream)
            {
                line = sr.ReadLine();
    
                // Perform a case-insensitive search by using the specified search options.
                testLine = line.ToUpper();
                if (trimSpaces) { testLine = testLine.Trim(); }
    
                switch (StringSearchOption)
                {
                    case StringSearchOption.StartsWith:
                        if (testLine.StartsWith(propertyName.ToUpper())) { results.Add(line); }
                        break;
                    case StringSearchOption.Contains:
                        if (testLine.Contains(propertyName.ToUpper())) { results.Add(line); }
                        break;
                    case StringSearchOption.EndsWith:
                        if (testLine.EndsWith(propertyName.ToUpper())) { results.Add(line); }
                        break;
                }
            }
        }
        catch
        {
            // Trap any exception that occurs in reading the file and return null.
            results = null;
        }
        finally
        {
            if (sr != null) {sr.Close();}
        }
    
        return results;
    }
    
  10. Po GetPropertyValue metoda, Dodaj następujący kod, aby zastąpić TryGetMember metoda DynamicObject klasy.TryGetMember Metoda jest wywoływana, gdy wymagane jest członkiem klasy dynamicznej i nie podano argumentów.binder Argument zawiera informacje o odwołanie członka i result wynik zwracany określony element członkowski odwołuje się argument.TryGetMember Metoda zwraca wartość logiczną, która zwraca true Jeżeli żądany element istnieje; w przeciwnym razie zwraca 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
    
    // Implement the TryGetMember method of the DynamicObject class for dynamic member calls. 
    public override bool TryGetMember(GetMemberBinder binder,
                                      out object result) 
    {
        result = GetPropertyValue(binder.Name);
        return result == null ? false : true;
    }
    
  11. Po TryGetMember metoda, Dodaj następujący kod, aby zastąpić TryInvokeMember metoda DynamicObject klasy.TryInvokeMember Metoda jest wywoływana, gdy wymagane jest członkiem klasy dynamicznej, z argumentami.binder Argument zawiera informacje o odwołanie członka i result wynik zwracany określony element członkowski odwołuje się argument.args Argument zawiera tablicę argumentów, które są przekazywane do członka.TryInvokeMember Metoda zwraca wartość logiczną, która zwraca true Jeżeli żądany element istnieje; w przeciwnym razie zwraca false.

    Niestandardową wersję TryInvokeMember metoda oczekuje, że pierwszy argument na wartość z StringSearchOption enum, zdefiniowanych w poprzednim kroku.TryInvokeMember Metoda oczekuje drugi argument na wartość logiczną.Jeśli jeden lub oba argumenty są prawidłowe wartości, są przekazywane do GetPropertyValue metoda pobierania 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
    
    // Implement the TryInvokeMember method of the DynamicObject class for  
    // dynamic member calls that have arguments. 
    public override bool TryInvokeMember(InvokeMemberBinder binder,
                                         object[] args,
                                         out object result)
    {
        StringSearchOption StringSearchOption = StringSearchOption.StartsWith;
        bool trimSpaces = true;
    
        try
        {
            if (args.Length > 0) { StringSearchOption = (StringSearchOption)args[0]; }
        }
        catch
        {
            throw new ArgumentException("StringSearchOption argument must be a StringSearchOption enum value.");
        }
    
        try
        {
            if (args.Length > 1) { trimSpaces = (bool)args[1]; }
        }
        catch
        {
            throw new ArgumentException("trimSpaces argument must be a Boolean value.");
        }
    
        result = GetPropertyValue(binder.Name, StringSearchOption, trimSpaces);
    
        return result == null ? false : true;
    }
    
  12. Zapisz i zamknij plik.

Aby utworzyć przykładowy plik tekstowy

  1. Kliknij prawym przyciskiem myszy projekt DynamicSample i wskaż Dodaj, a następnie kliknij przycisk Nowego elementu.W Szablonów okienka, a następnie kliknij polecenie Wybierz Ogólne, a następnie wybierz Plik tekstowy szablonu.Pozostaw domyślną nazwę TextFile1.txt w Nazwa , a następnie kliknij przycisk Dodaj.Nowy plik tekstowy jest dodawane do projektu.

  2. Skopiuj następujący tekst do pliku TextFile1.txt.

    List of customers and suppliers
    
    Supplier: Lucerne Publishing (http://www.lucernepublishing.com/)
    Customer: Preston, Chris
    Customer: Hines, Patrick
    Customer: Cameron, Maria
    Supplier: Graphic Design Institute (http://www.graphicdesigninstitute.com/) 
    Supplier: Fabrikam, Inc. (http://www.fabrikam.com/) 
    Customer: Seubert, Roxanne
    Supplier: Proseware, Inc. (https://www.proseware.com/) 
    Customer: Adolphi, Stephan
    Customer: Koch, Paul
    
  3. Zapisz i zamknij plik.

Aby utworzyć przykładową aplikację, która używa niestandardowych obiektów dynamicznych

  1. W Solution Explorer, kliknij dwukrotnie plik Module1.vb, korzystając z Visual Basic lub pliku Program.cs, jeśli używasz Visual C#.

  2. Dodaj następujący kod w procedurze głównej, aby utworzyć wystąpienie ReadOnlyFile klasy dla pliku TextFile1.txt.W kodzie wykorzystano późne wiązanie dynamiczne członków i pobierania wierszy tekstu, które zawierają 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
    
    dynamic rFile = new ReadOnlyFile(@"..\..\TextFile1.txt");
    foreach (string line in rFile.Customer)
    {
        Console.WriteLine(line);
    }
    Console.WriteLine("----------------------------");
    foreach (string line in rFile.Customer(StringSearchOption.Contains, true))
    {
        Console.WriteLine(line);
    }
    
  3. Zapisz plik i naciśnij kombinację klawiszy CTRL + F5, aby skompilować i uruchomić aplikację.

Wywołanie biblioteki dynamicznej języka

Następny projekt, które są tworzone w tym instruktażu uzyskuje dostęp do biblioteki, napisany w języku dynamiczne Boo.Przed utworzeniem tego projektu, musi mieć Boo 2.6.1 dla zainstalowany .NET w wersji 4.0.Można pobrać Boo 2.6.1 dla .NET w wersji 4.0 z CodePlex.

Aby utworzyć niestandardowe klasy dynamicznej

  1. W Visual Studio, na pliku menu, wskaż Nowa , a następnie kliknij przycisk Projekt.

  2. W Nowy projekt okno dialogowe, w Typów projektu w okienka, upewnij się, że Windows jest zaznaczone.Wybierz Console Application w Szablony okienko.W Nazwa wpisz DynamicIronPythonSample, a następnie kliknij przycisk OK.Tworzenia nowego projektu.

  3. Jeśli używasz Visual Basic, kliknij prawym przyciskiem myszy projekt DynamicIronPythonSample, a następnie kliknij przycisk Właściwości.Kliknij przycisk odwołania kartę.Kliknij przycisk Dodaj przycisk.Jeśli używasz Visual C#, w Solution Explorer, kliknij prawym przyciskiem myszy odwołania folder, a następnie kliknij przycisk Dodaj odwołanie.

  4. Na ludzie kartę, przejdź do folderu, w którym są zainstalowane biblioteki Boo.Na przykład C:\Program Files\IronPython 2.6 dla .NET w wersji 4.0.Wybierz IronPython.dll, IronPython.Modules.dll, Microsoft.Scripting.dll, i Microsoft.Dynamic.dll biblioteki.Kliknij przycisk OK.

  5. Jeśli używasz Visual Basic, Edytuj plik Module1.vb.Jeśli używasz Visual C#, należy edytować plik Program.cs.

  6. Na początku pliku, Dodaj następujący kod, aby zaimportować Microsoft.Scripting.Hosting i IronPython.Hosting nazw z bibliotek Boo.

    Imports Microsoft.Scripting.Hosting
    Imports IronPython.Hosting
    
    using Microsoft.Scripting.Hosting;
    using IronPython.Hosting;
    
  7. Metody Main, Dodaj następujący kod, aby utworzyć nowy Microsoft.Scripting.Hosting.ScriptRuntime obiektu do obsługi biblioteki Boo.ScriptRuntime Random.py Boo biblioteki moduł ładowania obiektu.

    ' Set the current directory to the IronPython libraries.
    My.Computer.FileSystem.CurrentDirectory = 
       My.Computer.FileSystem.SpecialDirectories.ProgramFiles &
       "\IronPython 2.6 for .NET 4.0\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.")
    
    // Set the current directory to the IronPython libraries.
    System.IO.Directory.SetCurrentDirectory(
       Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + 
       @"\IronPython 2.6 for .NET 4.0\Lib");
    
    // Create an instance of the random.py IronPython library.
    Console.WriteLine("Loading random.py");
    ScriptRuntime py = Python.CreateRuntime();
    dynamic random = py.UseFile("random.py");
    Console.WriteLine("random.py loaded.");
    
  8. Po kodzie załadować modułu random.py Dodaj następujący kod do utworzenia tablicy liczb całkowitych.Tablica jest przekazywana do shuffle metoda modułu random.py 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
    
    // Initialize an enumerable set of integers. 
    int[] items = Enumerable.Range(1, 7).ToArray();
    
    // Randomly shuffle the array of integers by using IronPython. 
    for (int i = 0; i < 5; i++)
    {
        random.shuffle(items);
        foreach (int item in items)
        {
            Console.WriteLine(item);
        }
        Console.WriteLine("-------------------");
    }
    
  9. Zapisz plik i naciśnij kombinację klawiszy CTRL + F5, aby skompilować i uruchomić aplikację.

Zobacz też

Informacje

System.Dynamic

DynamicObject

dynamic (odwołanie w C#)

Koncepcje

Wczesne i późne wiązania (Visual Basic)

Inne zasoby

Używanie typu dynamicznego (Przewodnik programowania w języku C#)

Implementowanie interfejsów dynamiczne (blog zewnętrznych)