C’è un modo per eseguire il casting di tipo implicito dinamico in C #?

Data questa class con un operatore di cast implicito:

public class MyDateTime { public static implicit operator MyDateTime(System.Int64 encoded) { return new MyDateTime(encoded); } public MyDateTime(System.Int64 encoded) { _encoded = encoded; } System.Int64 _encoded; } 

Ora posso fare quanto segue:

 long a = 5; MyDateTime b = a; 

Ma NON il seguente:

 long f = 5; object g = f; MyDateTime h = g; 

Questo dà un tempo di compilazione:

Imansible convertire implicitamente il tipo “object” in “MyDateTime”.

È sensato per me.

Ora modifico l’esempio precedente come segue:

 long f = 5; object g = f; MyDateTime h = (MyDateTime)g; 

Questo compila bene. Ora ricevo un runtime InvalidCastException :

Imansible eseguire il cast dell’object di tipo ‘System.Int64’ per digitare MyDateTime ‘.

Questo mi dice che gli operatori di cast impliciti di C # vengono applicati solo in fase di compilazione e non vengono applicati quando il runtime .NET sta tentando di trasmettere dynamicmente un object a un altro tipo.

Le mie domande:

  1. Ho ragione?
  2. C’è un altro modo per farlo?

A proposito, l’applicazione completa è che sto usando Delegate.DynamicInvoke() per chiamare una funzione che accetta un parametro MyDateTime e il tipo di argomento che sto passando a DynamicInvoke è lungo.

Ho ragione?

Sì, sì lo sei. Per essere pignoli, dovresti dire “conversione implicita definita dall’utente” piuttosto che “cast implicito” – un cast è (quasi) sempre esplicito. Ma la tua deduzione che la risoluzione di sovraccarico sceglie quale conversione definita dall’utente da chiamare in fase di compilazione e non in fase di esecuzione è corretta.

C’è un altro modo per farlo?

Sì. In C # 4 se si digita il “object” come “dinamico”, si riavvia il compilatore in fase di esecuzione e si eseguono nuovamente tutte le analisi sugli operandi come se i tipi di compilazione fossero i tipi correnti di esecuzione . Come puoi immaginare, questo non è economico, anche se siamo molto furbi nel caching e nel riutilizzo dei risultati se lo fai in un ciclo stretto.

So che questa è una domanda più vecchia, ma nel caso in cui qualcun altro si imbatta nello stesso problema, questo verrà compilato ed eseguito correttamente:

 long f = 5; object g = f; MyDateTime h = g as MyDateTime; 

L’aggiunta di un operatore esplicito dovrebbe funzionare: http://msdn.microsoft.com/en-us/library/85w54y0a(VS.80).aspx