Tipo anonimo vs tipo dinamico

Quali sono le reali differenze tra il tipo anonimo (var) in c # 3.0 e il tipo dinamico (dinamico) che sta arrivando in c # 4.0?

Un tipo anonimo è un tipo generato dal compilatore reale che viene creato per te. La cosa buona è che il compilatore può riutilizzare questo tipo in seguito per altre operazioni che lo richiedono in quanto è un POCO.

La mia comprensione dei tipi dinamici è che sono legati in ritardo, il che significa che il CLR (o DLR) valuterà l’object al momento dell’esecuzione e quindi utilizzerà la digitazione anatra per consentire o impedire l’accesso ai membri all’object.

Quindi suppongo che la differenza sia che i tipi anonimi sono veri POCO che il compilatore può vedere, ma puoi usare solo e i tipi dinamici sono oggetti dinamici legati in ritardo.

Sembra che tu stia mescolando tre cose ortogonali completamente diverse:

  • tipizzazione statica e dynamic
  • manifest o digitazione implicita
  • nome contro tipi anonimi

Questi tre aspetti sono completamente indipendenti, non hanno assolutamente nulla a che fare l’uno con l’altro.

La tipizzazione statica e quella dynamic si riferiscono al momento in cui avviene la verifica del tipo: la tipizzazione dynamic avviene in fase di esecuzione , la tipizzazione statica avviene prima del runtime .

Manifestazione rispetto alla tipizzazione implicita si riferisce al fatto che i tipi siano manifest nel codice sorgente o no: digit digit significa che il programmatore deve scrivere i tipi nel codice sorgente, la digitazione implicita significa che il sistema di tipi li individua da solo.

I tipi con nome e anonimi si riferiscono, beh, se i tipi hanno nomi o no.

La parola chiave dynamic in C # 4.0 significa che questa variabile, parametro, metodo, campo, proprietà … qualsiasi cosa è digitata dynamicmente , vale a dire che il suo tipo verrà controllato in fase di runtime. Tutto ciò che non è digitato come dinamico è tipizzato staticamente. Se un tipo è statico o dinamico, non determina solo quando avviene il controllo del tipo, ma in C # 4.0 determina anche, quando avviene la spedizione del metodo . In C #, la distribuzione dei metodi viene eseguita prima del runtime, in base al tipo statico (con l’eccezione del polimorfismo del sottotipo di runtime ovviamente), mentre sugli oggetti dynamicmente tipizzati in C # 4.0, la distribuzione dei metodi viene eseguita in fase di esecuzione, in base al tipo di runtime.

La parola chiave var in C # 3.0 significa che questa variabile locale sarà digitata implicitamente , ovvero che al posto del programmatore che scrive il tipo in modo esplicito, il sistema di tipi lo individuerà da solo. Questo non ha nulla a che fare con la digitazione dynamic, almeno in C # 3.0. La variabile sarà fortemente tipizzata staticamente come se tu avessi scritto tu stesso il testo. È semplicemente una comodità: ad esempio, perché dovresti scrivere due volte tutti i nomi dei tipi in HashMap foo = new HashMap(); quando il sistema di tipi può capire chiaramente che foo è un HashMap , quindi si scrive var foo = new HashMap . Si prega di notare che non c'è nulla di dinamico o anonimo in merito. Il tipo è statico e ha un nome: HashMap . Certamente, in C # 4.0, se il sistema di tipi rileva che il lato destro del compito è dinamico, il tipo di variabile sul lato sinistro sarà dinamico.

Un tipo anonimo in C # 3.0 significa che questo tipo non ha nome. Beh, in realtà, i veri tipi anonimi avrebbero richiesto una modifica retrotriggers al Common Type System, quindi quello che succede dietro le quinte è che il compilatore genererà un nome molto lungo, molto casuale, univoco e illegale per il tipo e il put quel nome ovunque appaia il tipo anonimo. Ma dal punto di vista del programmatore, il tipo non ha nome. Perché è utile? Bene, a volte hai risultati intermedi che ti servono solo brevemente e poi buttano via di nuovo. Dare a questi tipi transienti un nome proprio li eleverebbe ad un livello di importanza che semplicemente non meritano. Ma di nuovo, non c'è nulla di dinamico in questo.

Quindi, se il tipo non ha un nome, come può far riferimento il programmatore? Bene, non può! Almeno non direttamente. Ciò che il programmatore può fare è descrivere il tipo: ha due proprietà, una chiamata "nome" di tipo string , l'altra chiamata "id" di tipo int . Questo è il tipo che voglio, ma non mi interessa come si chiama.

Qui è dove i pezzi iniziano a venire insieme. In C #, devi dichiarare i tipi di variabili locali scrivendo esplicitamente i nomi dei tipi. Ma come si scrive il nome di un tipo che non ha nome? È qui che var entra in gioco: poiché dal momento che C # 3.0, questo non è più vero: non è più necessario scrivere i nomi, è anche ansible dire al compilatore di capirlo. Quindi, mentre quello che ho scritto nel primo paragrafo sopra è vero, che la tipizzazione implicita e i tipi anonimi non hanno nulla a che fare con altri, è anche vero che i tipi anonimi sarebbero piuttosto inutili senza digitare implicitamente.

Si noti, tuttavia, che il contrario non è vero: la digitazione implicita è perfettamente utile senza tipi anonimi. var foo = HashMap ha perfettamente senso e non c'è un tipo anonimo in vista.

Il tipo dynamic è essenzialmente object , ma risolverà tutte le chiamate metodo / proprietà / operatore, ecc. In fase di runtime tramite il DLR o altro provider (come la riflessione).

Questo lo rende molto simile a VB con Option Strict Off , e lo rende molto versatile per chiamare in COM o in tipi di DLR.

Non c’è nessun tipo di verifica in fase di compilazione con dynamic; Connessamente, i tipi anonimi sono bestie tipizzate staticamente corrette, controllate dal tipo (puoi vederle in reflector, anche se non sono carine).

Inoltre, i tipi anonimi possono essere gestiti esclusivamente dal compilatore; dynamic richiede un ampio supporto di runtime – quindi i tipi anonimi sono una caratteristica C #, ma la dynamic sarà in gran parte implementata da .NET 4.0 (con qualche supporto C # 4.0).

Controlla la presentazione di Ander qui:

http://channel9.msdn.com/pdc2008/TL16/

HTM

C’è tre volte, con tre attori – uno in ogni tempo.

  • Design-time – programmatore
  • Compile-time – c # compiler
  • Runtime – .net runtime

I tipi anonimi sono dichiarati e nominati dal compilatore. Questa dichiarazione è basata sulle specifiche del programmatore (come ha usato il tipo). Poiché questi tipi prendono il nome dal programmatore che ha lasciato il processo, sembrano essere senza nome per il programmatore, quindi “anonimo”.

  • Il programmatore dice: alcuni tipi hanno un nome e un indirizzo
  • Il compilatore dice: C’è un tipo chiamato xyz con proprietà e campi Nome e Indirizzo, entrambe le stringhe.
  • il runtime dice: non posso dire alcuna differenza tra xyz e qualsiasi tipo fatto dal programmatore.

la digitazione dynamic in c # consente di chiamare metodi che possono o meno esistere in fase di compilazione. Questo è utile per chiamare in python o javascript, che non sono compilati.

  • Il programmatore dice: considera questa istanza di un’auto come un tipo dinamico. Ora, ciarlatano.
  • Il compilatore dice: digitando dynamicmente eh? deve essere ok Non mi lamenterò perché non posso controllarlo.
  • Il runtime tenta di creare l’istanza della macchina, ciarlatano.

Niente come un piccolo codice per chiarire le cose:

 // anonymous types var anonType = new {Id = "123123123", Name = "Goku", Age = 30, DateAdded = new DateTime()}; // notice we have a strongly typed anonymous class we can access the properties with Console.WriteLine($"Anonymous Type: {anonType.Id} {anonType.Name} {anonType.Age} {anonType.DateAdded}"); // compile time error //anonType = 100; // dynamic types dynamic dynType = 100.01m; Console.WriteLine($"Dynamic type: {dynType}"); // it's ok to change the type however you want dynType = new List(); Console.WriteLine($"Dynamic type: {dynType}"); // mix dynamic and anonymous dynamic dynamicAnonymousType = new {Id = 8000, FirstName = "Goku", Gender = "male", IsSuperSaiyan = true}; // Wasn't sure this would work but it does! However, you lose intellisense on the FirstName so you have to type it manually. Console.WriteLine($"FirstName: {dynamicAnonymousType.FirstName}"); dynamicAnonymousType = 100; Console.WriteLine(dynamicAnonymousType); // runtime error Console.WriteLine($"Id: {dynamicAnonymousType.FirstName}");