Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Dynamické objekty zpřístupňují členy, jako jsou vlastnosti a metody za běhu, a ne v době kompilace. Dynamické objekty umožňují vytvářet objekty pro práci se strukturami, které neodpovídají statickému typu nebo formátu. Pomocí dynamického objektu můžete například odkazovat na model DOM (Document Object Model) HTML, který může obsahovat libovolnou kombinaci platných elementů a atributů značek HTML. Vzhledem k tomu, že každý dokument HTML je jedinečný, jsou členové konkrétního dokumentu HTML určeni během provádění. Běžnou metodou odkazování na atribut elementu HTML je předat název atributu GetProperty metodě elementu. Chcete-li odkazovat na id atribut HTML elementu <div id="Div1">, nejprve získáte odkaz na <div> element a pak použijete divElement.GetProperty("id"). Pokud používáte dynamický objekt, můžete odkazovat na id atribut jako divElement.id.
Dynamické objekty také poskytují pohodlný přístup k dynamickým jazykům, jako je IronPython a IronRuby. Dynamický objekt můžete použít k odkazování na dynamický skript interpretovaný za běhu.
Na dynamický objekt odkazujete pomocí pozdní vazby. Typ pozdního vázaného objektu zadáte jako dynamic. Další informace najdete v dynamickém.
Vlastní dynamické objekty můžete vytvořit 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řídu. Potom můžete přepsat členy DynamicObject třídy, aby poskytovaly dynamickou funkčnost za běhu.
Tento článek obsahuje dva nezávislé praktické příklady:
- Vytvořte vlastní objekt, který dynamicky zveřejňuje obsah textového souboru jako vlastnosti objektu.
- Vytvořte projekt, který používá knihovnu
IronPython.
Požadavky
- Visual Studio 2022 verze 17.3 nebo novější s nainstalovanou úlohou vývoje desktopových aplikací .NET Sada .NET 7 SDK je zahrnuta při výběru této úlohy.
Poznámka:
Počítač může v následujících pokynech zobrazit různé názvy nebo umístění některých prvků uživatelského rozhraní sady Visual Studio. Edice sady Visual Studio, kterou máte, a nastavení, která používáte, určují tyto prvky. Další informace najdete v tématu Přizpůsobeníintegrovaného vývojového prostředí (IDE).
- Pro druhý názorný postup nainstalujte IronPython pro .NET. Přejděte na stránku Pro stažení a získejte nejnovější verzi.
Vytvoření vlastního dynamického objektu
První návod definuje vlastní dynamický objekt, který prohledá obsah textového souboru. Dynamická vlastnost určuje hledaný text. Pokud například volání kódu určuje dynamicFile.Sample, dynamická třída vrátí obecný seznam řetězců, které obsahují všechny řádky ze souboru, které začínají na "Sample". Hledání nerozlišuje malá a velká písmena. Dynamická třída podporuje také dva volitelné argumenty. Prvním argumentem je hodnota výčtu možností hledání, která určuje, že dynamická třída by měla hledat shody na začátku řádku, na konci řádku nebo kdekoli na řádku. Druhý argument určuje, že dynamická třída by měla před hledáním oříznout úvodní a koncové mezery z každého řádku. Pokud například kódové volání určuje dynamicFile.Sample(StringSearchOption.Contains), dynamická třída vyhledá "Sample" kdekoli v řádku. Pokud volání kódu určuje dynamicFile.Sample(StringSearchOption.StartsWith, false), dynamická třída hledá výraz "Sample" na začátku každého řádku a neodstraňuje úvodní ani koncové mezery. Výchozím chováním dynamické třídy je vyhledání shody na začátku každého řádku a odebrání úvodních a koncových mezer.
Vytvoření vlastní dynamické třídy
Spusťte Visual Studio. Vyberte Vytvořit nový projekt. V dialogovém okně Vytvořit nový projekt vyberte C#, vyberte Konzolová aplikace a pak vyberte Další. V dialogovém okně Konfigurovat nový projekt zadejte DynamicSamplenázev projektu a pak vyberte Další. V dialogovém okně Další informace vyberte .NET 7.0 (Aktuální) pro cílovou architekturu a pak vyberte Vytvořit. V Průzkumníku řešení klikněte pravým tlačítkem na projekt DynamicSample a vyberte Přidat>třídu. Do pole Název zadejte ReadOnlyFilea pak vyberte Přidat. V horní části souboru ReadOnlyFile.cs nebo ReadOnlyFile.vb přidejte následující kód pro import jmenných prostorů System.IO a System.Dynamic.
using System.IO;
using System.Dynamic;
Vlastní dynamický objekt používá výčt 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
}
Aktualizujte příkaz třídy tak, aby dědil DynamicObject třídu, jak je znázorněno v následujícím příkladu kódu.
class ReadOnlyFile : DynamicObject
Do třídy přidejte následující kód ReadOnlyFile , který definuje privátní pole pro cestu k souboru a konstruktor pro ReadOnlyFile třídu.
// 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;
}
- Do třídy přidejte následující
GetPropertyValuemetoduReadOnlyFile. MetodaGetPropertyValuepřebírá jako vstupní kritéria kritéria hledání a vrací řádky z textového souboru, který odpovídá hledanému kritériu. Dynamické metody poskytovanéReadOnlyFiletřídou volají metoduGetPropertyValuepro načtení příslušných výsledků.
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;
}
Za metodu GetPropertyValue přidejte následující kód, který přepíše TryGetMember metodu DynamicObject třídy. Metoda TryGetMember je volána, když je požadován člen dynamické třídy a nejsou zadány žádné argumenty. Argument binder obsahuje informace o odkazovaném členu a result argument odkazuje na výsledek vrácený pro zadaný člen. Metoda TryGetMember vrátí logickou hodnotu, která vrátí true , pokud požadovaný člen existuje; jinak vrátí false.
// 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;
}
Za metodu TryGetMember přidejte následující kód, který přepíše TryInvokeMember metodu DynamicObject třídy. Metoda TryInvokeMember je volána, když člen dynamické třídy je požadován s argumenty. Argument binder obsahuje informace o odkazovaném členu a result argument odkazuje na výsledek vrácený pro zadaný člen. Argument args obsahuje pole argumentů, které jsou předány členu. Metoda TryInvokeMember vrátí logickou hodnotu, která vrátí true , pokud požadovaný člen existuje; jinak vrátí false.
Vlastní verze TryInvokeMember metody očekává, že první argument bude hodnotou z výčtu StringSearchOption , který jste definovali v předchozím kroku. Metoda TryInvokeMember očekává, že druhým argumentem bude logická hodnota. Pokud je jeden z argumentů nebo oba argumenty platnými hodnotami, jsou předány metodě GetPropertyValue k načtení výsledků.
// 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;
}
Uložte a zavřete soubor.
Vytvoření ukázkového textového souboru
V Průzkumníku řešení klikněte pravým tlačítkem na projekt DynamicSample a vyberte Přidat>novou položku. V podokně Nainstalované šablony vyberte Obecné a pak vyberte šablonu Textové soubory . V poli Název ponechte výchozí název TextFile1.txt a pak vyberte Přidat. Zkopírujte následující text do souboruTextFile1.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
Uložte a zavřete soubor.
Vytvoření ukázkové aplikace, která používá vlastní dynamický objekt
V Průzkumníku řešení poklikejte na soubor Program.cs . Do procedury přidejte následující kód Main , který vytvoří instanci ReadOnlyFile třídy pro TextFile1.txt soubor. Kód používá pozdní vazbu k volání dynamických členů a načtení řádků textu, které obsahují řetězec "Customer".
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);
}
Uložte soubor a stisknutím ctrl +F5 sestavte a spusťte aplikaci.
Volat dynamickou knihovnu jazyka
Následující názorný postup vytvoří projekt, který přistupuje k knihovně napsané v dynamickém jazyce IronPython.
Vytvoření vlastní dynamické třídy
V prostředí Visual Studio vyberte Soubor>Nový>Projekt. V dialogovém okně Vytvořit nový projekt vyberte C#, vyberte Konzolová aplikace a pak vyberte Další. V dialogovém okně Konfigurovat nový projekt zadejte DynamicIronPythonSamplenázev projektu a pak vyberte Další. V dialogovém okně Další informace vyberte .NET 7.0 (Aktuální) pro cílovou architekturu a pak vyberte Vytvořit. Nainstalujte balíček NuGet IronPython . Upravte soubor Program.cs . V horní části souboru přidejte následující kód pro import oborů názvů Microsoft.Scripting.Hosting a IronPython.Hosting z knihoven IronPython a oboru názvů System.Linq.
using System.Linq;
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;
Do metody Main přidejte následující kód pro vytvoření nového Microsoft.Scripting.Hosting.ScriptRuntime objektu pro hostování knihoven IronPython. Objekt ScriptRuntime načte modul knihovny 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");
ScriptRuntime py = Python.CreateRuntime();
dynamic random = py.UseFile("random.py");
Console.WriteLine("random.py loaded.");
Po načtení kódu modulu random.py přidejte následující kód, který vytvoří pole celých čísel. Pole se předává metodě shuffle modulu random.py, která náhodně seřadí hodnoty v tomto poli.
// 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("-------------------");
}
Uložte soubor a stisknutím ctrl +F5 sestavte a spusťte aplikaci.