Sdílet prostřednictvím


Postupy: Vytváření a používání dynamických objektů (C# a Visual Basic)

Dynamické objekty vystavit členy jako vlastnosti a metody v době běhu místo v v době kompilace.Umožňuje vytvořit objekty pracovat struktur, které neodpovídají formátu nebo statického typu.Můžete například dynamický objekt chcete-li odkazovat HTML Document Object Model (DOM), které mohou obsahovat libovolnou kombinaci platné prvky HTML značek a atributů.Každý dokument HTML je jedinečný členy pro určitý dokument HTML jsou určeny v době běhu.Metodu odkazu atribut elementu HTML je předat název atributu GetProperty metoda element.Odkaz id atribut elementu HTML <div id="Div1">, nejprve získat odkaz na <div> prvek a poté divElement.GetProperty("id").Pokud používáte dynamický objekt, můžete odkazovat id jako atribut divElement.id.

Dynamické objekty poskytují také pohodlný přístup k dynamických jazyků, jako například IronPython a IronRuby.Dynamický objekt můžete odkazovat dynamické skript, který je interpretován v době běhu.

Dynamický objekt odkazu pomocí pozdní vazba.V jazyce C#, zadejte typ objektu pozdní vazbou jako dynamic.V Visual Basic, zadejte typ objektu s pozdní vazbou jako Object.Další informace naleznete v tématu dynamic (Referenční dokumentace jazyka C#) a Statické a pozdní vazby (Visual Basic).

Můžete vytvářet vlastní dynamické objekty pomocí tříd v System.Dynamic oboru názvů.Můžete například vytvořit ExpandoObject a zadat členy tohoto objektu za běhu.Můžete také vytvořit vlastní typ, který dědí DynamicObject třídy.Potom můžete přepsat členy DynamicObject dynamických funkcí běhové třídy.

V tomto návodu budete provádět následující úkoly:

  • Vytvořte vlastní objekt, který dynamicky zpřístupňuje obsah textového souboru jako vlastnosti objektu.

  • Vytvořit projekt, který používá IronPython knihovny.

Požadavky

Potřebujete IronPython 2.6.1 .NET 4.0 pro dokončení tohoto návodu.Můžete stáhnout IronPython 2.6.1 .NET 4.0 z CodePlex.

[!POZNÁMKA]

Na vašem počítači se můžou v následujících pokynech zobrazovat jiné názvy nebo umístění některých prvků uživatelského rozhraní Visual Studia. Tyto prvky jsou určeny edicí sady Visual Studio a použitým nastavením. Další informace najdete v tématu Přizpůsobení nastavení pro vývoj v sadě Visual Studio.

Vytvoření vlastní dynamický objekt

Definuje první projekt, který v tomto návodu vytvoříte vlastní dynamický objekt, který prohledá obsah textového souboru.Hledaný text je určen název dynamické vlastnosti.Například pokud volání kódu určuje dynamicFile.Sample, dynamické třídy vrátí obecný seznam řetězců obsahující všechny řádky ze souboru, začínající "Vzorku".Hledání nerozlišuje velká a malá písmena.Dynamická třída také podporuje dva nepovinné argumenty.První argument je hodnota výčtu možnost hledání, která určuje, že dynamické třídy by měl hledat na začátku řádku konec řádku nebo kdekoliv v řádku.Druhý argument určuje, že by počátečních a koncových mezer z každého řádku před prohledáním trim dynamické třídy.Například pokud volání kódu určuje dynamicFile.Sample(StringSearchOption.Contains), dynamické třídy hledá "Ukázkový" kdekoliv v řádku.Pokud volání kódu určuje dynamicFile.Sample(StringSearchOption.StartsWith, false), dynamické třídy hledá "Ukázkový" na začátku každého řádku a nedojde k odebrání počátečních a koncových mezer.Výchozí chování dynamické třídy je hledat na začátku každého řádku a k odebrání počátečních a koncových mezer.

Chcete-li vytvořit vlastní dynamické třídy

  1. Spusťte nástroj Visual Studio.

  2. V nabídce Soubor přejděte na příkaz Nový a klikněte na Projekt.

  3. V Nový projekt v dialogovém okně pole Typy projektu podokně Ujistěte se, že Windows je vybrán.Vyberte Aplikace konzoly v šablony podokno.V název zadejte DynamicSamplea klepněte na tlačítko OK.Je vytvořen nový projekt.

  4. Pravým tlačítkem na projekt DynamicSample a přejděte na příkaz Přidata klepněte na tlačítko třídy.V název zadejte ReadOnlyFilea klepněte na tlačítko OK.Přidán nový soubor, který obsahuje třídu ReadOnlyFile.

  5. V horní části souboru ReadOnlyFile.cs nebo ReadOnlyFile.vb přidejte následující kód k importu System.IO a System.Dynamic obory názvů.

    Imports System.IO
    Imports System.Dynamic
    
    using System.IO;
    using System.Dynamic;
    
  6. Vlastní dynamický objekt enum používá k určení kritérií hledání.Před příkaz třídy přidejte následující definici výčtu.

    Public Enum StringSearchOption
        StartsWith
        Contains
        EndsWith
    End Enum
    
    public enum StringSearchOption
    {
        StartsWith,
        Contains,
        EndsWith
    }
    
  7. Aktualizovat výpis třídy dědí DynamicObject třídy, jak je znázorněno v následujícím příkladu kódu.

    Public Class ReadOnlyFile
        Inherits DynamicObject
    
    class ReadOnlyFile : DynamicObject
    
  8. Následující kód přidejte ReadOnlyFile definovat soukromé pole Cesta k souboru a konstruktor pro třídu ReadOnlyFile třídy.

    ' 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. Přidejte následující GetPropertyValue metoda ReadOnlyFile třídy.GetPropertyValue Metoda přebírá jako vstup kritéria hledání a vrátí řádky z textového souboru odpovídající, kritéria hledání.Dynamické metody poskytované ReadOnlyFile volání třídy GetPropertyValue metoda načíst jejich odpovídajících výsledků.

    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 metodu, přidejte následující kód přepsat TryGetMember metoda DynamicObject třídy.TryGetMember Metoda je volána, když je požadován členem dynamické třídy a jsou zadány žádné argumenty.binder Argument obsahuje informace o odkazované člen a result odkazuje argument Výsledek vrácený pro zadaný člen.TryGetMember Metoda vrátí logickou hodnotu, která vrací true Pokud dožádaný členský existuje; v opačném případě vrátí 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 metodu, přidejte následující kód přepsat TryInvokeMember metoda DynamicObject třídy.TryInvokeMember Metoda je volána, když je vyžádána členem dynamické třídy s argumenty.binder Argument obsahuje informace o odkazované člen a result odkazuje argument Výsledek vrácený pro zadaný člen.args Argument obsahuje pole argumentů, které jsou předány člena.TryInvokeMember Metoda vrátí logickou hodnotu, která vrací true Pokud dožádaný členský existuje; v opačném případě vrátí false.

    Vlastní verzi TryInvokeMember metoda očekává hodnotu z prvního argumentu StringSearchOption výčet, který jste definovali v předchozím kroku.TryInvokeMember Metoda očekává druhý argument logickou hodnotu.Pokud jeden nebo oba argumenty jsou platné hodnoty, jsou předány do GetPropertyValue metodu pro získání výsledků.

    ' 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. Soubor uložte a zavřete.

Vytvořte textový soubor vzorku

  1. Pravým tlačítkem na projekt DynamicSample a přejděte na příkaz Přidata klepněte na tlačítko Nová položka.V Nainstalované šablony podokně vyberte Obecnéa pak vyberte Textový soubor šablony.Ponechat výchozí název TextFile1.txt v název a klepněte na tlačítko Přidat.Nový textový soubor je přidán do projektu.

  2. Zkopírujte následující text do souboru 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. Soubor uložte a zavřete.

Vytvořit ukázkové aplikace, která používá vlastní objekt dynamické

  1. V Průzkumníku, poklepejte na soubor Module1.vb, pokud používáte Visual Basic nebo Program.cs soubor, pokud používáte Visual C#.

  2. Přidejte následující kód hlavní procedury k vytvoření instance ReadOnlyFile třídy souboru TextFile1.txt.Kód používá pozdní vazba volání dynamických členů a načíst řádky textu, které obsahují řetězec "Zákazník".

    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. Uložte soubor a stiskněte CTRL + F5 sestavit a spustit aplikaci.

Volání knihovny dynamických jazyků

Další projekt, který vytvoříte v tomto návodu přistupuje, dynamický jazyk IronPython knihovny.Před vytvořením projektu, musí mít IronPython 2.6.1 .NET 4.0 nainstalován.Můžete stáhnout IronPython 2.6.1 .NET 4.0 z CodePlex.

Chcete-li vytvořit vlastní dynamické třídy

  1. V Visual Studio, na soubor příkaz Nový a potom klepněte na tlačítko projektu.

  2. V Nový projekt v dialogovém okně pole Typy projektu podokně Ujistěte se, že Windows je vybrán.Vyberte Aplikace konzoly v šablony podokno.V název zadejte DynamicIronPythonSamplea klepněte na tlačítko OK.Je vytvořen nový projekt.

  3. Pokud používáte Visual Basicklepněte pravým tlačítkem na projekt DynamicIronPythonSample a Vlastnosti.Klikněte na záložku Odkazy.Klepněte na tlačítko Přidat.Pokud používáte Visual C#, Průzkumníku, klepněte pravým tlačítkem myši odkazy složky a pak klepněte na Přidat odkaz.

  4. Na Procházet karta, vyhledejte složku, kde jsou nainstalovány IronPython knihoven.Například C:\Program .NET 4.0 2.6 Files\IronPython.Vyberte IronPython.dll, IronPython.Modules.dll, Microsoft.Scripting.dll, a Microsoft.Dynamic.dll knihovny.Klikněte na tlačítko OK.

  5. Pokud používáte Visual Basic, úpravy souboru Module1.vb.Pokud používáte Visual C#, upravte soubor Program.cs.

  6. V horní části souboru přidejte následující kód k importu Microsoft.Scripting.Hosting a IronPython.Hosting obory názvů z knihovny IronPython.

    Imports Microsoft.Scripting.Hosting
    Imports IronPython.Hosting
    
    using Microsoft.Scripting.Hosting;
    using IronPython.Hosting;
    
  7. V metodě hlavní přidejte následující kód pro vytvoření nového Microsoft.Scripting.Hosting.ScriptRuntime objektu knihovny IronPython hostitele.ScriptRuntime Random.py modulu knihovny IronPython načtení objektu.

    ' 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 načtení random.py modulu kódu přidejte následující kód pro vytvoření pole celých čísel.Pole je předána shuffle random.py modulu náhodně řadí hodnoty v poli Metoda.

    ' 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. Uložte soubor a stiskněte CTRL + F5 sestavit a spustit aplikaci.

Viz také

Referenční dokumentace

System.Dynamic

DynamicObject

dynamic (Referenční dokumentace jazyka C#)

Koncepty

Statické a pozdní vazby (Visual Basic)

Další zdroje

Použití typu dynamic (Průvodce programováním v C#)

Implementace rozhraní dynamické (externí blog)