Uso del tipo dinamico

Il tipo dynamic è statico, ma un oggetto di tipo dynamicignora il controllo del tipo statico. Nella maggior parte dei casi, funziona come se disponesse del tipo object. Il compilatore presuppone che un elemento dynamic supporti qualsiasi operazione. Pertanto, non è necessario determinare se l'oggetto ottiene il valore da un'API COM, da un linguaggio dinamico come IronPython, dal modello DOM (Document Object Model) HTML, dalla reflection o da un'altra parte del programma. Tuttavia, se il codice non è valido, gli errori vengono visualizzati in fase di esecuzione.

Se, ad esempio, il metodo di istanza exampleMethod1 nel codice seguente dispone di un solo parametro, il compilatore riconosce che la prima chiamata al metodo, ec.exampleMethod1(10, 4), non è valida perché contiene due argomenti. La chiamata genera errori di compilazione. Il compilatore non controlla la seconda chiamata al metodo, dynamic_ec.exampleMethod1(10, 4), perché il tipo di dynamic_ec è dynamic. Non viene, pertanto, segnalato alcun errore del compilatore. L'errore, tuttavia, non viene ignorato indefinitamente. Viene intercettato in fase di esecuzione e provoca un'eccezione in tale fase.

static void Main(string[] args)
{
    ExampleClass ec = new ExampleClass();
    // The following call to exampleMethod1 causes a compiler error
    // if exampleMethod1 has only one parameter. Uncomment the line
    // to see the error.
    //ec.exampleMethod1(10, 4);

    dynamic dynamic_ec = new ExampleClass();
    // The following line is not identified as an error by the
    // compiler, but it causes a run-time exception.
    dynamic_ec.exampleMethod1(10, 4);

    // The following calls also do not cause compiler errors, whether
    // appropriate methods exist or not.
    dynamic_ec.someMethod("some argument", 7, null);
    dynamic_ec.nonexistentMethod();
}
class ExampleClass
{
    public ExampleClass() { }
    public ExampleClass(int v) { }

    public void exampleMethod1(int i) { }

    public void exampleMethod2(string str) { }
}

Il ruolo del compilatore in questi esempi consiste nel raggruppare le informazioni su ciò che ogni istruzione propone di fare all'oggetto dynamic o all'espressione. Il runtime esamina le informazioni archiviate e qualsiasi istruzione non valida causa un'eccezione in fase di esecuzione.

Il risultato della maggior parte delle operazioni dinamiche è dynamic. Se, ad esempio, si posiziona il puntatore del mouse sull'utilizzo di testSum nell'esempio seguente, IntelliSense visualizza il tipo (variabile locale) dynamic testSum.

dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);

Le operazioni in cui il risultato non è dynamic includono:

  • Le conversioni da dynamic a un altro tipo.
  • Le chiamate al costruttore che includono argomenti di tipo dynamic.

Il tipo di testInstance, ad esempio, nella dichiarazione seguente è ExampleClass, non dynamic:

var testInstance = new ExampleClass(d);

Conversioni

Le conversioni tra oggetti dinamici e altri tipi sono facili. Le conversioni consentono allo sviluppatore di passare dal comportamento dinamico a quello non dinamico e viceversa.

È possibile convertire qualsiasi dynamic in modo implicito, come illustrato negli esempi seguenti.

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

Al contrario, è possibile applicare dinamicamente qualsiasi conversione alle espressioni di tipo dynamic.

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

Risoluzione dell'overload con argomenti di tipo dinamico

La risoluzione dell'overload si verifica in fase di esecuzione anziché in fase di compilazione se uno o più argomenti in una chiamata al metodo dispongono del tipo dynamic o se il ricevitore della chiamata al metodo è di tipo dynamic. Nell'esempio seguente, se il solo metodo exampleMethod2 accessibile è definito in modo che accetti un argomento di tipo stringa, l'invio di d1 come argomento non provoca un errore del compilatore, bensì un'eccezione in fase di esecuzione. La risoluzione dell'overload non riesce in fase di esecuzione perché il tipo in fase di esecuzione di d1 è int e exampleMethod2 richiede una stringa.

// Valid.
ec.exampleMethod2("a string");

// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);

Dynamic Language Runtime

Il runtime del linguaggio dinamico (DLR) fornisce l'infrastruttura che supporta il tipo dynamic in C# oltre all'implementazione di linguaggi di programmazione dinamici, quali IronPython e IronRuby. Per altre informazioni su DLR, vedere Dynamic Language Runtime Overview (Panoramica su Dynamic Language Runtime).

interoperabilità COM

Diversi metodi COM consentono la variazione nei tipi di argomento e nel tipo restituito designando i tipi come object. L'interoperabilità COM richiede il cast esplicito dei valori per coordinarli con le variabili fortemente tipizzate in C#. Se si esegue la compilazione usando l'opzione EmbedInteropTypes (opzioni del compilatore C#), l'introduzione del tipo dynamic consente di trattare le occorrenze di object nelle firme COM come se fossero di tipo dynamic, evitando così gran parte del cast. Per altre informazioni sull'uso del tipo dynamic con gli oggetti COM, vedere l'articolo Come accedere agli oggetti di interoperabilità di Office usando le funzionalitàdi C#.

Posizione Descrizione
dynamic Viene descritto l'utilizzo della parola chiave dynamic.
Dynamic Language Runtime Overview (Panoramica su Dynamic Language Runtime) Viene fornita una panoramica di DLR, un ambiente di runtime che estende Common Language Runtime (CLR) con un set di servizi per linguaggi dinamici.
Procedura dettagliata: Creazione e utilizzo di oggetti dinamici Fornisce istruzioni dettagliate per la creazione di un oggetto dinamico personalizzato e per la creazione di un progetto che accede a una libreria IronPython.