Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dynamische Objekte machen Elemente wie Eigenschaften und Methoden zur Laufzeit statt zur Kompilierungszeit verfügbar. Mit dynamischen Objekten können Sie Objekte erstellen, um mit Strukturen zu arbeiten, die nicht mit einem statischen Typ oder Format übereinstimmen. Sie können z. B. ein dynamisches Objekt verwenden, um auf das HTML-Dokumentobjektmodell (DOM) zu verweisen, das eine beliebige Kombination aus gültigen HTML-Markupelementen und -attributen enthalten kann. Da jedes HTML-Dokument eindeutig ist, werden die Member für ein bestimmtes HTML-Dokument zur Laufzeit bestimmt. Eine gängige Methode zum Verweisen auf ein Attribut eines HTML-Elements besteht darin, den Namen des Attributs an die GetProperty
Methode des Elements zu übergeben. Um auf das id
Attribut des HTML-Elements <div id="Div1">
zu verweisen, erhalten Sie zuerst einen Verweis auf das <div>
Element, und verwenden Sie divElement.GetProperty("id")
dann . Wenn Sie ein dynamisches Objekt verwenden, können Sie auf das id
Attribut verweisen als divElement.id
.
Dynamische Objekte bieten auch bequemen Zugriff auf dynamische Sprachen wie IronPython und IronRuby. Sie können ein dynamisches Objekt verwenden, um sich auf ein dynamisches Skript zu beziehen, das zur Laufzeit ausgeführt wird.
Sie verweisen auf ein dynamisches Objekt mithilfe einer verspäteten Bindung. Sie geben den Typ eines spät gebundenen Objekts als dynamic
an. Weitere Informationen finden Sie unter dynamisch.
Sie können benutzerdefinierte dynamische Objekte mithilfe der Klassen im System.Dynamic Namespace erstellen. Sie können z. B. zur Laufzeit ein ExpandoObject erstellen und die Mitglieder dieses Objekts angeben. Sie können auch ihren eigenen Typ erstellen, der die DynamicObject Klasse erbt. Sie können die Member dieser DynamicObject-Klasse anschließend außer Kraft setzen, um dynamische Funktionen zur Laufzeit bereitzustellen.
Dieser Artikel enthält zwei voneinander unabhängige exemplarische Vorgehensweisen:
- Erstellen Sie ein benutzerdefiniertes Objekt, das den Inhalt einer Textdatei dynamisch als Eigenschaften eines Objekts verfügbar macht.
- Erstellen Sie ein Projekt, das eine
IronPython
Bibliothek verwendet.
Voraussetzungen
- Visual Studio 2022, Version 17.3 oder höher , mit installierter .NET-Desktopentwicklungsworkload . Das .NET 7 SDK ist enthalten, wenn Sie diese Workload auswählen.
Hinweis
Auf Ihrem Computer werden möglicherweise unterschiedliche Namen oder Speicherorte für einige der Visual Studio-Benutzeroberflächenelemente in den folgenden Anweisungen angezeigt. Die Visual Studio-Edition, über die Sie verfügen, und die Einstellungen, die Sie verwenden, bestimmen diese Elemente. Weitere Informationen finden Sie unter Personalisierung der IDE.
- Installieren Sie IronPython für .NET für die zweite Anleitung. Wechseln Sie zur Downloadseite , um die neueste Version zu erhalten.
Erstellen eines benutzerdefinierten dynamischen Objekts
Die erste exemplarische Vorgehensweise definiert ein benutzerdefiniertes dynamisches Objekt, das den Inhalt einer Textdatei durchsucht. Eine dynamische Eigenschaft gibt den text an, nach dem gesucht werden soll. Wenn beispielsweise der aufrufende Code angibt dynamicFile.Sample
, gibt die dynamische Klasse eine generische Liste von Zeichenfolgen zurück, die alle Zeilen aus der Datei enthält, die mit "Sample" beginnen. Die Groß- und Kleinschreibung wird bei der Suche nicht berücksichtigt. Die dynamische Klasse unterstützt auch zwei optionale Argumente. Das erste Argument ist ein Enumerationswert für Suchoptionen, der angibt, dass die dynamische Klasse am Anfang der Zeile, am Ende der Zeile oder an einer beliebigen Stelle in der Zeile nach Übereinstimmungen suchen soll. Das zweite Argument gibt an, dass die dynamische Klasse vor der Suche die führenden und nachfolgenden Leerzeichen aus jeder Zeile entfernt. Wenn beispielsweise der aufrufte Code angibt dynamicFile.Sample(StringSearchOption.Contains)
, sucht die dynamische Klasse an einer beliebigen Stelle in einer Zeile nach "Sample". Wenn der Aufrufcode angibt dynamicFile.Sample(StringSearchOption.StartsWith, false)
, sucht die dynamische Klasse am Anfang jeder Zeile nach "Sample", und entfernt keine führenden und nachgestellten Leerzeichen. Das Standardverhalten der dynamischen Klasse besteht darin, am Anfang jeder Zeile nach einer Übereinstimmung zu suchen und führende und nachfolgende Leerzeichen zu entfernen.
Erstellen einer benutzerdefinierten dynamischen Klasse
Starten Sie Visual Studio. Wählen Sie Neues Projekt erstellen aus. Wählen Sie im Dialogfeld " Neues Projekt erstellen " C# und dann "Konsolenanwendung" und dann "Weiter" aus. Geben Sie im Dialogfeld "DynamicSample
" den Projektnamen ein, und wählen Sie dann "Weiter" aus. Wählen Sie im Dialogfeld "Zusätzliche Informationen " .NET 7.0 (Aktuell) für das Zielframework und dann "Erstellen" aus. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das DynamicSample-Projekt, und wählen Sie"Klasse> aus. Geben Sie im ReadOnlyFile
" den Namen ein, und wählen Sie dann "Hinzufügen" aus. Fügen Sie oben in der datei ReadOnlyFile.cs oder ReadOnlyFile.vb den folgenden Code hinzu, um die System.IOSystem.Dynamic Namespaces zu importieren.
using System.IO;
using System.Dynamic;
Das benutzerdefinierte dynamische Objekt verwendet eine Enumeration, um die Suchkriterien zu bestimmen. Fügen Sie vor der Klassen-Anweisung die folgende Enum-Definition hinzu.
public enum StringSearchOption
{
StartsWith,
Contains,
EndsWith
}
Aktualisieren Sie die Klassen-Anweisung, um die DynamicObject
Klasse zu erben, wie im folgenden Codebeispiel gezeigt.
class ReadOnlyFile : DynamicObject
Fügen Sie der ReadOnlyFile
Klasse den folgenden Code hinzu, um ein privates Feld für den Dateipfad und einen Konstruktor für die ReadOnlyFile
Klasse zu definieren.
// 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;
}
- Fügen Sie der
GetPropertyValue
Klasse die folgendeReadOnlyFile
Methode hinzu. DieGetPropertyValue
Methode verwendet als Eingabekriterien suchkriterien und gibt die Zeilen aus einer Textdatei zurück, die diesen Suchkriterien entsprechen. Die von derReadOnlyFile
Klasse bereitgestellten dynamischen Methoden rufen dieGetPropertyValue
Methode auf, um ihre jeweiligen Ergebnisse abzurufen.
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;
}
Fügen Sie nach der GetPropertyValue
Methode den folgenden Code hinzu, um die TryGetMember Methode der DynamicObject Klasse außer Kraft zu setzen. Die TryGetMember Methode wird aufgerufen, wenn ein Element einer dynamischen Klasse angefordert wird und keine Argumente angegeben werden. Das binder
Argument enthält Informationen zum element, auf das verwiesen wird, und das result
Argument verweist auf das für das angegebene Element zurückgegebene Ergebnis. Die TryGetMember Methode gibt einen booleschen Wert zurück, der zurückgibt true
, wenn das angeforderte Element vorhanden ist; andernfalls wird der Wert zurückgegeben 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;
}
Fügen Sie nach der TryGetMember
Methode den folgenden Code hinzu, um die TryInvokeMember Methode der DynamicObject Klasse außer Kraft zu setzen. Die TryInvokeMember Methode wird aufgerufen, wenn ein Element einer dynamischen Klasse mit Argumenten angefordert wird. Das binder
Argument enthält Informationen zum element, auf das verwiesen wird, und das result
Argument verweist auf das für das angegebene Element zurückgegebene Ergebnis. Das args
Argument enthält ein Array der Argumente, die an das Element übergeben werden. Die TryInvokeMember Methode gibt einen booleschen Wert zurück, der zurückgibt true
, wenn das angeforderte Element vorhanden ist; andernfalls wird der Wert zurückgegeben false
.
Die benutzerdefinierte Version der TryInvokeMember
-Methode erwartet, dass das erste Argument ein Wert aus dem StringSearchOption
-Enum ist, den Sie in einem vorherigen Schritt definiert haben. Die TryInvokeMember
Methode erwartet, dass das zweite Argument ein boolescher Wert ist. Wenn ein oder beide Argumente gültige Werte sind, werden sie an die GetPropertyValue
Methode übergeben, um die Ergebnisse abzurufen.
// 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;
}
Speichern und schließen Sie die Datei.
Erstellen einer Beispieltextdatei
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das DynamicSample-Projekt, und wählen Sie "Neues Element> aus. Wählen Sie im Bereich "Installierte Vorlagen " die Option "Allgemein" und dann die Textdateivorlage aus. Behalten Sie den Standardnamen von TextFile1.txt im Feld "Name " bei, und wählen Sie dann "Hinzufügen" aus. Kopieren Sie den folgenden Text in die dateiTextFile1.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
Speichern und schließen Sie die Datei.
Erstellen einer Beispielanwendung, die das benutzerdefinierte dynamische Objekt verwendet
Doppelklicken Sie im Projektmappen-Explorer auf die Program.cs Datei. Fügen Sie der Main
Prozedur den folgenden Code hinzu, um eine Instanz der ReadOnlyFile
Klasse für die TextFile1.txt Datei zu erstellen. Der Code verwendet späte Bindung, um dynamische Member aufzurufen und Textzeilen abzurufen, die die Zeichenfolge "Customer" enthalten.
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);
}
Speichern Sie die Datei, und drücken Sie STRG+F5 , um die Anwendung zu erstellen und auszuführen.
Aufrufen einer dynamischen Sprachbibliothek
Die folgende exemplarische Vorgehensweise erstellt ein Projekt, das auf eine Bibliothek zugreift, die in der dynamischen Sprache IronPython geschrieben wurde.
So erstellen Sie eine benutzerdefinierte dynamische Klasse
Klicken Sie in Visual Studio auf Datei>Neu>Projekt. Wählen Sie im Dialogfeld " Neues Projekt erstellen " C# und dann "Konsolenanwendung" und dann "Weiter" aus. Geben Sie im Dialogfeld "DynamicIronPythonSample
" den Projektnamen ein, und wählen Sie dann "Weiter" aus. Wählen Sie im Dialogfeld "Zusätzliche Informationen " .NET 7.0 (Aktuell) für das Zielframework und dann "Erstellen" aus. Installieren Sie das IronPython NuGet-Paket. Bearbeiten Sie die Program.cs Datei. Fügen Sie oben in der Datei den folgenden Code hinzu, um die Microsoft.Scripting.Hosting
und IronPython.Hosting
Namespaces aus den IronPython-Bibliotheken und den System.Linq
Namespace zu importieren.
using System.Linq;
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;
Fügen Sie in der Main-Methode den folgenden Code hinzu, um ein neues Microsoft.Scripting.Hosting.ScriptRuntime
Objekt zum Hosten der IronPython-Bibliotheken zu erstellen. Das ScriptRuntime
Objekt lädt das IronPython-Bibliotheksmodul 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.");
Fügen Sie nach dem Code zum Laden des random.py Moduls den folgenden Code hinzu, um ein Array mit ganzen Zahlen zu erstellen. Das Array wird an die shuffle
Methode des random.py Moduls übergeben, das die Werte im Array zufällig sortiert.
// 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("-------------------");
}
Speichern Sie die Datei, und drücken Sie STRG+F5 , um die Anwendung zu erstellen und auszuführen.