Carenze nell'uso dei tipi dinamici in C #


14

Di recente ho studiato di più sui tipi dinamici in C #. Con alcuni esempi ho capito una volta compilato il codice, non è necessario ricompilarlo di nuovo, ma può essere eseguito direttamente.

Ritengo che la flessibilità fornita dalla parola chiave per poter effettivamente cambiare il tipo di dati a piacimento sia un grande vantaggio .

Domanda,

Esistono carenze specifiche oltre a chiamate errate di metodi dinamici che generano eccezioni di runtime che gli sviluppatori devono conoscere prima di iniziare l'implementazione.


3
In C # 3, ho sempre considerato l'uso objecto il cast di tipi diretti come un odore di codice. In quasi tutti i casi significava che io o uno del mio team non avevamo progettato un'interfaccia appropriata per quella funzionalità. Immagino che se usassi C # 4 ora, mi sentirei praticamente allo stesso modo sull'uso di dynamicanch'io. Potrei vedere il caso se rendessi tutto dinamico, ma in quel caso potresti anche aver selezionato una lingua tipizzata dinamica in primo luogo. * 8 ')
Mark Booth,

@MarkBooth +1 per la prospettiva. È quindi sicuro affermare che l'implementazione di base usando C # rimarrà fortemente tipizzata nonostante l'introduzione di tipi dinamici in 4.0
Karthik Sreenivasan,

L'uso dynamicin C # significa che non è necessario abbandonare IronPython se tutto ciò che serve è una digitazione dinamica per una piccola parte del codice. Per un valutatore di espressioni, ho avuto un grande successo usando dynamicper rappresentare gli operandi di un'espressione e i risultati della valutazione.
Ed James,

@EdJames - Sembra molto utile dynamic, inoltre vorrei sapere di IronPython quando stavo sviluppando con .Net - avrebbe potuto rendere certe cose che stavamo cercando di fare molto più facilmente.
Mark Booth,

Risposte:


16

Il difetto principale è che si elimina una delle proprietà principali (non necessariamente vantaggi) di C # - che è tipizzata staticamente (e per la maggior parte sicura del tipo di parte).

Il problema con la digitazione dinamica è che spesso nasconde bug che sarebbero altrimenti rivelati durante la compilazione. Tale bug si manifesta quindi solo in fase di esecuzione, il che ovviamente rende molto più difficile da rilevare.

Ci sono pochissime ragioni per usare l'OMO per usare la tipizzazione dinamica in C #, la principale è la collaborazione con linguaggi tipizzati dinamicamente (che è AFAIK il motivo per cui la dinamica è stata introdotta in primo luogo).

Se vuoi fare una programmazione tipizzata in modo completamente dinamico, dovresti guardare un linguaggio progettato per essere dinamico, non hackerare C # per essere dinamico. Ad esempio, è possibile utilizzare IronPython se si desidera utilizzare le librerie .Net


+1 per IronPython. Ciò significa che questo potrebbe portare a problemi di manutenzione a lungo termine.
Karthik Sreenivasan,

6
La cosa grande che dynamicti dà è la possibilità di eseguire l'upgrade di un oggetto al suo tipo reale senza alcun tipo di hack di riflessione. Ad esempio se Base foo = new Derived();e c'erano due metodi sovraccarichi Moo(Base x)e Moo(Derived x), quindi , Moo(foo)chiamate Moo(Base x), ma Moo((dynamic)foo)chiamate Moo(Derived x). Ciò porta ad esempio a un'implementazione molto elegante del modello Visitor: code.logos.com/blog/2010/03/… ed è in generale una tecnica molto potente.

@TheMouthofaCow Bello, ci sono sicuramente alcuni altri usi "legittimi" anche per la dinamica, tuttavia questi sono pochi e lontani tra loro (e devi assolutamente sapere cosa stai facendo prima di provare qualcosa del genere).
Matěj Zábský,

@TheMouthofaCow Un modello di design relativamente nuovo (The Visitor Pattern) da notare. Grazie.
Karthik Sreenivasan,

1
Sì, è abbastanza bello. L'ho escogitato in modo indipendente la scorsa settimana, quindi è stato bello vedere che è un'idea accettata che è stata adottata nell'arsenale C #.

9

Non sono sicuro che tipo di carenze stai cercando, ma se vuoi conoscere le funzionalità che funzionano con la digitazione statica, ma non con dynamic, ci sono alcune:

  1. I metodi di estensione non funzionano. Questo è probabilmente il più grande. Se hai dynamic collection, non puoi usare un codice simile collection.Distinct(). Questo perché i metodi di estensione disponibili dipendono usingdallo spazio dei nomi e il DLR non ha modo di conoscerli.

    Come soluzione alternativa, è possibile richiamare il metodo come se fosse normale metodo statico: Enumerable.Distinct(collection). Oppure puoi cambiare il tipo di raccolta in qualcosa del genere IEnumerable<dynamic>.

  2. foreachrichiede IEnumerable. In C # normale, foreachè basato su pattern. Cioè, non richiede alcuna interfaccia specifica, solo un GetEnumerator()metodo che restituisce l'oggetto adatto. Se si utilizza foreachsu dynamic, IEnumerableè necessaria l'implementazione di . Ma poiché la ragione di questo comportamento è che C # 1.0 non aveva generici, questo "difetto" è praticamente irrilevante.


+1 per il metodo delle estensioni. Questo vale anche per altri operatori di query LINQ come GroupBy ()?
Karthik Sreenivasan,

2
@Karthik: Sì. Penso che i metodi di estensione siano zucchero sintattico in fase di compilazione, quindi il fatto che non vengano risolti.

@TheMouthofaCow +1 - Grazie per il chiarimento.
Karthik Sreenivasan,

1
Sono d'accordo con i metodi di estensione, vale a dire come la dinamica non è in grado di capire i metodi di estensione in fase di esecuzione, ma non ho potuto seguire la raccolta dinamica che hai spiegato.
Karthik Sreenivasan,

7

Il problema con i tipi dinamici (non variabili dichiarate come dinamiche) in .net è che non hanno molte funzionalità disponibili per i tipi statici.

  • non c'è riflessione (puoi iterare sui membri ma non molto altro)
  • nessun metadata (va la tua convalida in siti di dati dinamici / mvc)
  • assolutamente nessun controllo al momento della compilazione (eventuali errori di ortografia non verranno rilevati)
  • poiché questa è una potente funzione, i noob possono tendere ad abusare / abusare / fraintenderlo
  • il codice scritto con tipi dinamici tende ad essere difficile da mantenere e dannatamente difficile da refactoring
  • a causa della digitazione anatra e di altre funzionalità, i guru possono scrivere codice illeggibile per chiunque altro

Quindi non scrivere codice con tipi dinamici a meno che tu non sappia cosa stai facendo.


6

Poiché dynamicè solo un contrassegnato object, racchiude i tipi di valore.

Ciò può avere implicazioni sulle prestazioni, ma dal momento che userei comunque la tipizzazione statica nel codice critico per le prestazioni, probabilmente non è un problema in pratica.

Questa boxe interferisce anche con i tipi di valori modificabili. Se li modifichi con dynamic, modifichi solo la copia in scatola. Ma dal momento che non dovresti usare tipi di valori mutabili in primo luogo, anche questo non è un grosso problema.


+1 Sono assolutamente d'accordo. La digitazione statica sarebbe l'approccio migliore per il codice critico per le prestazioni.
Karthik Sreenivasan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.