Il passaggio dell’object dinamico al metodo C # modifica il tipo di reso

Ho creato una class che eredita DynamicObject e voglio creare un metodo statico in grado di creare nuove istanze con proprietà predeterminate (memorizzate nel Dictionary ).

 public class CustomDynamic : DynamicObject { protected Dictionary InnerDictionary; public static T Create(Dictionary dictionary) where T : CustomDynamic , new() { return new T { InnerDictionary = dictionary }; } } 

Uso:

 dynamic d = new Dictionary(); var realPlayer = CustomDynamic.Create(d as Dictionary); var dynaPlayer = CustomDynamic.Create(d); realPlayer // Player type according to VS2013 dynaPlayer // dynamic type according to VS2013 

Poiché esiste una sola firma del metodo, perché passare in un ritorno dinamico un object dinamico? O in realtà solo Visual Studio 2013 si confonde?

Questo perché quasi tutte le operazioni che coinvolgono un valore dinamico vengono risolte dynamicmente al momento dell’esecuzione. Non ci sono eccezioni per i casi in cui in realtà esiste un solo metodo presente in fase di compilazione; la lingua è più semplice in questo modo. (Per alcune chiamate, il compilatore esegue una risoluzione sufficiente in fase di compilazione per garantire che ci sia almeno un metodo con un numero adeguato di parametri – questo è specificato nella specifica C # 5 nella sezione 7.5.4, ma ciò non influisce sul tipo di reso effettivo).

Dalla specifica C # 5, sezione 7.6.5:

Un’espressione di chiamata viene associata dynamicmente se almeno uno dei seguenti elementi contiene:

  • L’ espressione primaria ha un tipo dynamic fase di compilazione.
  • Almeno un argomento dell’argomento-argomento facoltativo ha un tipo di fase di compilazione dynamic e l’ espressione principale non ha un tipo delegato.

In questo caso il compilatore classifica l’ espressione di chiamata come un valore di tipo dynamic . […]

Ci sono alcune operazioni che coinvolgono valori dinamici che hanno ancora un tipo generale non dinamico. Per esempio:

  • d is Foo è sempre bool
  • d as Foo è sempre Foo
  • new Foo(d) è sempre Foo anche se il costruttore esatto da usare è determinato al momento dell’esecuzione

Ma ogni chiamata al metodo viene considerata come avente un tipo di ritorno dynamic .

È come funziona la dynamic. Da MSDN

La risoluzione del sovraccarico si verifica in fase di esecuzione anziché in fase di compilazione se uno o più argomenti in una chiamata di metodo hanno il tipo dinamico o se il destinatario della chiamata al metodo è di tipo dinamico.

Potresti pensare di non avere sovraccarichi aggiuntivi per il tuo metodo ma potresti averlo. Il compilatore non esegue questo controllo in fase di compilazione, ecco perché si vede il tipo di dynaPlayer come dinamico al posto di Player .