Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Gli oggetti dinamici espongono membri, ad esempio proprietà e metodi in fase di esecuzione, anziché in fase di compilazione. Gli oggetti dinamici consentono di creare oggetti da utilizzare con strutture che non corrispondono a un tipo o formato statico. Ad esempio, è possibile usare un oggetto dinamico per fare riferimento al DOM (Document Object Model) HTML, che può contenere qualsiasi combinazione di attributi e elementi di markup HTML validi. Poiché ogni documento HTML è univoco, i membri di un particolare documento HTML vengono determinati in fase di esecuzione. Un metodo comune per fare riferimento a un attributo di un elemento HTML consiste nel passare il nome dell'attributo al GetProperty metodo dell'elemento. Per fare riferimento all'attributo dell'elemento HTML id<div id="Div1">, per prima cosa ottenere un riferimento all'elemento <div> e quindi usare divElement.GetProperty("id"). Se si usa un oggetto dinamico, è possibile fare riferimento all'attributo id come divElement.id.
Gli oggetti dinamici forniscono anche un pratico accesso ai linguaggi dinamici, ad esempio IronPython e IronRuby. È possibile usare un oggetto dinamico per fare riferimento a uno script dinamico interpretato in fase di esecuzione.
Per fare riferimento a un oggetto dinamico, usare l'associazione tardiva. Specifica il tipo di un oggetto ad associazione tardiva come dynamic. Per ulteriori informazioni, vedere dynamic.
È possibile creare oggetti dinamici personalizzati utilizzando le classi nello spazio dei nomi System.Dynamic. Ad esempio, è possibile creare un oggetto ExpandoObject e specificare i membri di tale oggetto in fase di esecuzione. È anche possibile creare un tipo personalizzato che eredita la DynamicObject classe . È quindi possibile eseguire l'override dei membri della DynamicObject classe per fornire funzionalità dinamiche in fase di esecuzione.
Questo articolo contiene due procedure dettagliate indipendenti:
- Creare un oggetto personalizzato che espone dinamicamente il contenuto di un file di testo come proprietà di un oggetto .
- Creare un progetto che usa una
IronPythonlibreria.
Prerequisiti
- Visual Studio 2022 versione 17.3 o successiva con il pacchetto di sviluppo .NET sviluppo desktop installato. .NET 7 SDK è incluso quando si seleziona questo carico di lavoro.
Annotazioni
Il computer potrebbe visualizzare nomi o percorsi diversi per alcuni degli elementi dell'interfaccia utente di Visual Studio nelle istruzioni seguenti. L'edizione di Visual Studio disponibile e le impostazioni usate determinano questi elementi. Per altre informazioni, vedere Personalizzazione dell'IDE.
- Per la seconda procedura dettagliata, installare IronPython per .NET. Passare alla pagina download per ottenere la versione più recente.
Creare un oggetto dinamico personalizzato
La prima procedura dettagliata definisce un oggetto dinamico personalizzato che effettua una ricerca tra i contenuti di un file di testo. Una proprietà dinamica specifica il testo da cercare. Ad esempio, se il codice chiamante specifica dynamicFile.Sample, la classe dinamica restituisce un elenco generico di stringhe che contiene tutte le righe del file che iniziano con "Sample". La ricerca non fa distinzione tra maiuscole e minuscole. La classe dinamica supporta anche due argomenti facoltativi. Il primo argomento è un valore di enumerazione dell'opzione di ricerca che specifica che la classe dinamica deve cercare corrispondenze all'inizio della riga, alla fine della riga o in qualsiasi punto della riga. Il secondo argomento specifica che la classe dinamica deve tagliare gli spazi iniziali e finali da ogni riga prima della ricerca. Ad esempio, se il codice chiamante specifica dynamicFile.Sample(StringSearchOption.Contains), la classe dinamica cerca "Sample" ovunque in una riga. Se il codice chiamante specifica dynamicFile.Sample(StringSearchOption.StartsWith, false), la classe dinamica cerca "Sample" all'inizio di ogni riga e non rimuove spazi iniziali e finali. Il comportamento predefinito della classe dinamica consiste nel cercare una corrispondenza all'inizio di ogni riga e rimuovere spazi iniziali e finali.
Creare una classe dinamica personalizzata
Avvia Visual Studio. Selezionare Crea un nuovo progetto. Nella finestra di dialogo Crea un nuovo progetto selezionare C#, selezionare Applicazione console e quindi selezionare Avanti. Nella finestra di dialogo Configura il nuovo progetto immettere DynamicSample per Nome progetto e quindi selezionare Avanti. Nella finestra di dialogo Informazioni aggiuntive selezionare .NET 7.0 (Corrente) per Framework di destinazione e quindi selezionare Crea. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto DynamicSample e scegliere Aggiungi>classe. Nella casella Nome digitare ReadOnlyFilee quindi selezionare Aggiungi. Nella parte superiore del file ReadOnlyFile.cs o ReadOnlyFile.vb aggiungete il seguente codice per importare i namespace System.IO e System.Dynamic.
using System.IO;
using System.Dynamic;
L'oggetto dinamico personalizzato usa un'enumerazione per determinare i criteri di ricerca. Prima della dichiarazione della classe, aggiungere la seguente definizione di enum.
public enum StringSearchOption
{
StartsWith,
Contains,
EndsWith
}
Aggiornare l'istruzione di classe per ereditare la DynamicObject classe , come illustrato nell'esempio di codice seguente.
class ReadOnlyFile : DynamicObject
Aggiungere il codice seguente alla ReadOnlyFile classe per definire un campo privato per il percorso del file e un costruttore per la ReadOnlyFile classe .
// 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;
}
- Aggiungere il metodo seguente
GetPropertyValueallaReadOnlyFileclasse . IlGetPropertyValuemetodo accetta, come input, criteri di ricerca e restituisce le righe di un file di testo che corrispondono ai criteri di ricerca. I metodi dinamici forniti dallaReadOnlyFileclasse chiamano ilGetPropertyValuemetodo per recuperare i rispettivi risultati.
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;
}
Dopo il GetPropertyValue metodo, aggiungere il codice seguente per eseguire l'override del TryGetMember metodo della DynamicObject classe . Il TryGetMember metodo viene chiamato quando viene richiesto un membro di una classe dinamica e non vengono specificati argomenti. L'argomento binder contiene informazioni sul membro a cui si fa riferimento e l'argomento result fa riferimento al risultato restituito per il membro specificato. Il TryGetMember metodo restituisce un valore booleano che restituisce true se il membro richiesto esiste; in caso contrario, restituisce 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;
}
Dopo il TryGetMember metodo, aggiungere il codice seguente per eseguire l'override del TryInvokeMember metodo della DynamicObject classe . Il TryInvokeMember metodo viene chiamato quando viene richiesto un membro di una classe dinamica con argomenti. L'argomento binder contiene informazioni sul membro a cui si fa riferimento e l'argomento result fa riferimento al risultato restituito per il membro specificato. L'argomento args contiene una matrice degli argomenti passati al membro. Il TryInvokeMember metodo restituisce un valore booleano che restituisce true se il membro richiesto esiste; in caso contrario, restituisce false.
La versione personalizzata del TryInvokeMember metodo prevede che il primo argomento sia un valore dell'enumerazione StringSearchOption definita in un passaggio precedente. Il TryInvokeMember metodo prevede che il secondo argomento sia un valore booleano. Se uno o entrambi gli argomenti sono valori validi, vengono passati al GetPropertyValue metodo per recuperare i risultati.
// 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;
}
Salva e chiudi il file.
Creare un file di testo di esempio
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto DynamicSample e scegliere Aggiungi>nuovo elemento. Nel riquadro Modelli installati selezionare Generale e quindi selezionare il modello File di testo . Lasciare il nome predefinito di TextFile1.txt nella casella Nome e quindi selezionare Aggiungi. Copiare il testo seguente nel file TextFile1.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
Salva e chiudi il file.
Creare un'applicazione di esempio che usa l'oggetto dinamico personalizzato
In Esplora soluzioni fare doppio clic sul file Program.cs . Aggiungere il codice seguente alla Main routine per creare un'istanza della ReadOnlyFile classe per il file TextFile1.txt . Il codice usa l'associazione tardiva per chiamare membri dinamici e recuperare righe di testo che contengono la stringa "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);
}
Salvare il file e premere CTRL+F5 per compilare ed eseguire l'applicazione.
Chiamare una libreria del linguaggio dinamico
La procedura dettagliata seguente crea un progetto che accede a una libreria scritta nel linguaggio dinamico IronPython.
Per creare una classe dinamica personalizzata
In Visual Studio selezionare File>Nuovo>Progetto. Nella finestra di dialogo Crea un nuovo progetto selezionare C#, selezionare Applicazione console e quindi selezionare Avanti. Nella finestra di dialogo Configura il nuovo progetto immettere DynamicIronPythonSample per Nome progetto e quindi selezionare Avanti. Nella finestra di dialogo Informazioni aggiuntive selezionare .NET 7.0 (Corrente) per Framework di destinazione e quindi selezionare Crea. Installare il pacchetto NuGet IronPython . Modificare il file Program.cs . Nella parte superiore del file, aggiungere il codice seguente per importare gli spazi dei nomi Microsoft.Scripting.Hosting e IronPython.Hosting dalle librerie IronPython e il namespace System.Linq.
using System.Linq;
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;
Nel metodo Main aggiungere il codice seguente per creare un nuovo Microsoft.Scripting.Hosting.ScriptRuntime oggetto per ospitare le librerie IronPython. L'oggetto ScriptRuntime carica il modulo della libreria 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.");
Dopo il codice per caricare il modulo random.py, aggiungere il codice seguente per creare una matrice di numeri interi. La matrice viene passata al shuffle metodo del modulo random.py, che ordina in modo casuale i valori nella matrice.
// 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("-------------------");
}
Salvare il file e premere CTRL+F5 per compilare ed eseguire l'applicazione.