Quando non usare la dinamica in C # [chiuso]

2

Sto creando una classe simile alla seguente:

public class KeyValue
{
    public readonly string key;
    public readonly object value;
}

Il valore potrebbe essere di qualsiasi tipo di oggetto come conseguenza di questo design.

In alternativa, potrei usare la dinamica come valore e mi renderebbe la vita più facile, perché significherebbe nessun tipo di casting, e anche perché, per quanto comprendo, potrei usare i tipi di valore senza bisogno di box / Unbox.

C'è qualche ragione per non utilizzare la dinamica e usare invece l'oggetto? Perché non riesco a pensare a nessuno.

Nota: mi rendo conto che i generici sono molto più adatti a questo, ma non funziona per i miei bisogni. Quanto sopra è davvero una semplificazione solo ai fini di questa domanda.

    
posta 9a3eedi 18.09.2014 - 02:30
fonte

4 risposte

14

Se non riesci a pensare ad una buona ragione per usare dinamica, allora stai rinunciando a potenziali controlli del tempo di compilazione per poco o nulla in cambio.

Preferisco i generici rispetto all'oggetto e preferisco l'oggetto rispetto alla dinamica, a meno che non sia necessario interagire con un linguaggio dinamico ScriptEngine o un contenitore dinamico come un modulo Web in cui è ragionevole gestire le potenziali eccezioni di runtime quando accedo a un campo mancante. Generics funzionerà al meglio; e con oggetto, stai almeno indicando che le tue intenzioni sono di memorizzare qualsiasi tipo di oggetto nello stesso contenitore.

La dinamica non è un tipo effettivo, e non è "oggetto", quindi dovrebbe mai essere usato per indicare "qualsiasi tipo di oggetto", dovrebbe effettivamente essere usato quando sapere qual è il contratto dell'oggetto (metodo / firma della proprietà); è un veicolo di dispacciamento runtime per mantenere la stessa sintassi comoda per un'attività non sicura (o almeno legata dinamicamente). È come dire:

"OK, I know the activity I'm doing is subject to runtime dispatch and runtime errors, so give me the syntactical sugar anyway"

Quando vedo dinamico, presumo di solito che sia imminente:

  1. richiama la chiamata del metodo a un tipo con collegamento dinamico (come una variabile IronPython)
  2. accesso a dati di moduli dinamici con sintassi di proprietà in un controller MVC

Anche se un altro uso legittimo è quello di utilizzare la capacità di invio dinamico per implementare il Visitor Pattern , anche se i metodi virtuali tradizionali sono probabilmente più veloci.

class FooVisitor {
     void Accept(Expression node) { ... }
     void Accept(Statement node) { ... }
}

foreach(dynamic node in ASTNodes) {
    visitor.Accept(obj);  // will be dispatched at runtime based on type of each obj
}

Non usarlo quando:

  1. Le prestazioni sono numero uno
  2. Il controllo statico del tipo è auspicabile per un runtime più robusto
  3. I tipi possono essere derivati in fase di compilazione
  4. Un tipo generico farà

Se usato inutilmente, la dinamica può effettivamente ridurre la robustezza del tuo codice cambiando C # in un linguaggio di scripting dinamico.

    
risposta data 18.09.2014 - 05:05
fonte
5

dynamic è stato introdotto principalmente come metodo per consentire a C # di interoperare con linguaggi come Python, che non è tipizzato staticamente. Se lo stai utilizzando in questo contesto probabilmente stai rinunciando a funzionalità.

Come hai detto, nel contesto limitato in cui ti presenti, stai molto meglio usando i generici (la classe KeyValuePair assomiglia molto a ciò che stai cercando di creare qui).

    
risposta data 18.09.2014 - 02:49
fonte
3

La risposta è che se i tipi dinamici migliorano il tuo codice, producono un risultato migliore e ti semplificano la vita, ovviamente devi usarli. Ecco a cosa servono!

Non dovresti assolutamente preoccuparti di boxe / unboxing, il che è piuttosto efficiente a parte l'imposizione di un certo carico sul garbage collector. Guarda il codice generato per i tipi dinamici e vedrai costi generali significativamente più elevati, ma non dovresti preoccuparti neanche di quelli.

La sfida in questo gioco è produrre codice corretto che tu e altre persone potete capire e lavorare con. Usa i generici se puoi, dinamico se funziona per te e gli oggetti grezzi se devi. Quindi benchmark prima di ottimizzare. O semplicemente vai avanti.

    
risposta data 18.09.2014 - 03:54
fonte
0

Se stai utilizzando object come tipo di variabile, e sei veramente sicuro di aver bisogno, e tu veramente sicuro che i generici non faranno ciò di cui hai bisogno, ci sono uno e mezzo di scenari che ho riscontrato dove non dovresti usare dynamic :

  1. Devi essere distribuito su macchine vecchie. Dynamic è disponibile solo con .NET 4.0, quindi se hai bisogno di supportare macchine che non sono garantite per averlo ... basta usare object .
  2. E seguendo linee simili, Xamarin (come alcuni mesi fa quando ne tenevo traccia) non aveva ancora un supporto stabile per le dinamiche. Questo tipo cade con # 1 - in sostanza, se la piattaforma di destinazione non li supporta, quindi non li usa.

Comunque sono variabili. dynamic come parametro di funzione fa sì che la funzione venga inviata dinamicamente. Questo è di solito quello che vuoi, ma non sempre. L'utilizzo di object utilizzerà la normale spedizione di sola istanza. In caso contrario, si applicano le stesse linee guida.

    
risposta data 18.09.2014 - 03:55
fonte

Leggi altre domande sui tag