Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Visual Basic supporta tipi anonimi, che consentono di creare oggetti senza scrivere una definizione di classe per il tipo di dati. Al contrario, il compilatore genera automaticamente una classe. La classe non ha un nome utilizzabile, eredita direttamente da Objecte contiene le proprietà specificate nella dichiarazione dell'oggetto. Poiché il nome del tipo di dati non è specificato, viene definito tipo anonimo.
Nell'esempio seguente viene dichiarata e creata una variabile product come istanza di un tipo anonimo con due proprietà e NamePrice.
' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}
Un'espressione di query usa tipi anonimi per combinare colonne di dati selezionate da una query. Non è possibile definire il tipo di risultato in anticipo, perché non è possibile stimare le colonne selezionate da una query specifica. I tipi anonimi consentono di scrivere una query che seleziona un numero qualsiasi di colonne, in qualsiasi ordine. Il compilatore crea un tipo di dati che corrisponde alle proprietà specificate e all'ordine specificato.
Negli esempi seguenti, products è un elenco di oggetti prodotto, ognuno dei quali ha molte proprietà. La variabile namePriceQuery contiene la definizione di una query che, quando viene eseguita, restituisce una raccolta di istanze di un tipo anonimo che ha due proprietà, Name e Price.
Dim namePriceQuery = From prod In products
Select prod.Name, prod.Price
La variabile nameQuantityQuery contiene la definizione di una query che, quando viene eseguita, restituisce una raccolta di istanze di un tipo anonimo che ha due proprietà, Name e OnHand.
Dim nameQuantityQuery = From prod In products
Select prod.Name, prod.OnHand
Per altre informazioni sul codice creato dal compilatore per un tipo anonimo, vedere Anonymous Type Definition.For more information about the code created by the compiler for an anonymous type definition, see Anonymous Type Definition.
Attenzione
Il nome del tipo anonimo viene generato dal compilatore e può variare dalla compilazione alla compilazione. Il codice non deve usare o basarsi sul nome di un tipo anonimo perché il nome potrebbe cambiare quando un progetto viene ricompilato.
Dichiarazione di un tipo anonimo
La dichiarazione di un'istanza di un tipo anonimo usa un elenco di inizializzatori per specificare le proprietà del tipo. È possibile specificare solo le proprietà quando si dichiara un tipo anonimo, non altri elementi della classe, ad esempio metodi o eventi. Nell'esempio seguente è product1 un'istanza di un tipo anonimo con due proprietà: Name e Price.
' Variable product1 is an instance of a simple anonymous type.
Dim product1 = New With {.Name = "paperclips", .Price = 1.29}
' -or-
' product2 is an instance of an anonymous type with key properties.
Dim product2 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Se si designano le proprietà come proprietà chiave, è possibile usarle per confrontare due istanze di tipo anonimo per verificarne l'uguaglianza. Non è tuttavia possibile modificare i valori delle proprietà chiave. Per altre informazioni, vedere la sezione Proprietà chiave più avanti in questo argomento.
Si noti che la dichiarazione di un'istanza di un tipo anonimo è simile alla dichiarazione di un'istanza di un tipo denominato tramite un inizializzatore di oggetto:
' Variable product3 is an instance of a class named Product.
Dim product3 = New Product With {.Name = "paperclips", .Price = 1.29}
Per altre informazioni su altri modi per specificare le proprietà dei tipi anonimi, vedere Procedura: Dedurre nomi di proprietà e tipi nelle dichiarazioni di tipo anonimo.
Proprietà chiave
Le proprietà chiave differiscono dalle proprietà non chiave in diversi modi fondamentali:
Vengono confrontati solo i valori delle proprietà chiave per determinare se due istanze sono uguali.
I valori delle proprietà chiave sono di sola lettura e non possono essere modificati.
Solo i valori delle proprietà chiave sono inclusi nell'algoritmo di codice hash generato dal compilatore per un tipo anonimo.
Uguaglianza
Le istanze di tipi anonimi possono essere uguali solo se sono istanze dello stesso tipo anonimo. Il compilatore considera due istanze come istanze dello stesso tipo se soddisfano le condizioni seguenti:
Essi vengono dichiarati nello stesso assembly.
Le relative proprietà hanno gli stessi nomi, gli stessi tipi dedotti e vengono dichiarati nello stesso ordine. I confronti dei nomi non fanno distinzione tra maiuscole e minuscole.
Le stesse proprietà in ognuna sono contrassegnate come proprietà chiave.
Almeno una proprietà in ogni dichiarazione è una proprietà chiave.
Un'istanza di un tipo anonimo che non ha proprietà chiave è uguale solo a se stessa.
' prod1 and prod2 have no key values.
Dim prod1 = New With {.Name = "paperclips", .Price = 1.29}
Dim prod2 = New With {.Name = "paperclips", .Price = 1.29}
' The following line displays False, because prod1 and prod2 have no
' key properties.
Console.WriteLine(prod1.Equals(prod2))
' The following statement displays True because prod1 is equal to itself.
Console.WriteLine(prod1.Equals(prod1))
Due istanze dello stesso tipo anonimo sono uguali se i valori delle relative proprietà della chiave sono uguali. Gli esempi seguenti illustrano come viene testata l'uguaglianza.
Dim prod3 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod4 = New With {Key .Name = "paperclips", Key .Price = 1.29}
' The following line displays True, because prod3 and prod4 are
' instances of the same anonymous type, and the values of their
' key properties are equal.
Console.WriteLine(prod3.Equals(prod4))
Dim prod5 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod6 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 423}
' The following line displays False, because prod5 and prod6 do not
' have the same properties.
Console.WriteLine(prod5.Equals(prod6))
Dim prod7 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 24}
Dim prod8 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 423}
' The following line displays True, because prod7 and prod8 are
' instances of the same anonymous type, and the values of their
' key properties are equal. The equality check does not compare the
' values of the non-key field.
Console.WriteLine(prod7.Equals(prod8))
Read-Only Valori
Non è possibile modificare i valori delle proprietà chiave. Ad esempio, nell'esempio prod8 precedente i Name campi e Price sono read-only, ma OnHand possono essere modificati.
' The following statement will not compile, because Name is a key
' property and its value cannot be changed.
' prod8.Name = "clamps"
' OnHand is not a Key property. Its value can be changed.
prod8.OnHand = 22
Tipi anonimi da espressioni di query
Le espressioni di query non richiedono sempre la creazione di tipi anonimi. Quando possibile, usano un tipo esistente per contenere i dati della colonna. Ciò si verifica quando la query restituisce record interi dall'origine dati o soltanto un campo da ogni record. Negli esempi di codice seguenti è customers una raccolta di oggetti di una Customer classe . La classe ha molte proprietà ed è possibile includerne una o più nel risultato della query, in qualsiasi ordine. Nei primi due esempi non sono necessari tipi anonimi perché le query selezionano elementi di tipi denominati:
custs1contiene una raccolta di stringhe, perchécust.Nameè una stringa.Dim custs1 = From cust In customers Select cust.Namecusts2contiene una raccolta diCustomeroggetti, perché ogni elemento dicustomersè unCustomeroggetto e l'intero elemento viene selezionato dalla query.Dim custs2 = From cust In customers Select cust
Tuttavia, i tipi denominati appropriati non sono sempre disponibili. È possibile selezionare i nomi e gli indirizzi dei clienti per uno scopo, i numeri ID cliente e le posizioni per un altro, nonché i nomi dei clienti, gli indirizzi e le cronologie degli ordini per un terzo. I tipi anonimi consentono di selezionare qualsiasi combinazione di proprietà, in qualsiasi ordine, senza prima dichiarare un nuovo tipo denominato per contenere il risultato. Il compilatore crea invece un tipo anonimo per ogni compilazione di proprietà. La query seguente seleziona solo il nome e il numero ID del cliente da ogni Customer oggetto in customers. Pertanto, il compilatore crea un tipo anonimo che contiene solo queste due proprietà.
Dim custs3 = From cust In customers
Select cust.Name, cust.ID
Sia i nomi che i tipi di dati delle proprietà nel tipo anonimo vengono tratti dagli argomenti a Select, cust.Name e cust.ID. Le proprietà di un tipo anonimo che viene generato da una query sono sempre proprietà chiave. Quando custs3 viene eseguito nel ciclo seguente For Each , il risultato è una raccolta di istanze di un tipo anonimo con due proprietà chiave e NameID.
For Each selectedCust In custs3
Console.WriteLine(selectedCust.ID & ": " & selectedCust.Name)
Next
Gli elementi della raccolta rappresentati da custs3 sono fortemente tipizzati ed è possibile usare IntelliSense per spostarsi tra le proprietà disponibili e per verificarne i tipi.
Per altre informazioni, vedere Introduzione a LINQ in Visual Basic.
Decidere se usare tipi anonimi
Prima di creare un oggetto come istanza di una classe anonima, valutare se si tratta dell'opzione migliore. Ad esempio, se si vuole creare un oggetto temporaneo per contenere dati correlati e non sono necessari altri campi e metodi che una classe completa potrebbe contenere, un tipo anonimo è una buona soluzione. I tipi anonimi sono utili anche se si desidera una selezione diversa di proprietà per ogni dichiarazione o se si desidera modificare l'ordine delle proprietà. Tuttavia, se il progetto include diversi oggetti con le stesse proprietà, in un ordine fisso, è possibile dichiararli più facilmente usando un tipo denominato con un costruttore di classe. Ad esempio, con un costruttore appropriato, è più facile dichiarare più istanze di una Product classe rispetto a quella di dichiarare diverse istanze di un tipo anonimo.
' Declaring instances of a named type.
Dim firstProd1 As New Product("paperclips", 1.29)
Dim secondProd1 As New Product("desklamp", 28.99)
Dim thirdProd1 As New Product("stapler", 5.09)
' Declaring instances of an anonymous type.
Dim firstProd2 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim secondProd2 = New With {Key .Name = "desklamp", Key .Price = 28.99}
Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}
Un altro vantaggio dei tipi denominati è che il compilatore può rilevare un errore di digitazione accidentale di un nome di proprietà. Negli esempi precedenti, firstProd2, secondProd2e thirdProd2 sono destinati a essere istanze dello stesso tipo anonimo. Tuttavia, se si dovesse dichiarare thirdProd2 accidentalmente in uno dei modi seguenti, il relativo tipo sarebbe diverso da quello di firstProd2 e secondProd2.
' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}
' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = "5.09"}
' Dim thirdProd2 = New With {Key .Name = "stapler", .Price = 5.09}
Più importante, esistono limitazioni sull'uso di tipi anonimi che non si applicano alle istanze di tipi denominati.
firstProd2, secondProd2e thirdProd2 sono istanze dello stesso tipo anonimo. Tuttavia, il nome per il tipo anonimo condiviso non è disponibile e non può essere visualizzato dove è previsto un nome di tipo nel codice. Ad esempio, non è possibile usare un tipo anonimo per definire una firma del metodo, dichiarare un'altra variabile o campo o in qualsiasi dichiarazione di tipo. Di conseguenza, i tipi anonimi non sono appropriati quando è necessario condividere informazioni tra metodi.
Definizione di tipo anonimo
In risposta alla dichiarazione di un'istanza di un tipo anonimo, il compilatore crea una nuova definizione di classe contenente le proprietà specificate.
Se il tipo anonimo contiene almeno una proprietà chiave, la definizione esegue l'override di tre membri ereditati da Object: Equals, GetHashCodee ToString. Il codice generato per testare l'uguaglianza e determinare il valore del codice hash considera solo le proprietà della chiave. Se il tipo anonimo non contiene proprietà chiave, viene eseguito l'override solo di ToString. Le proprietà denominate in modo esplicito di un tipo anonimo non possono essere in conflitto con questi metodi generati. Ciò significa che non è possibile usare .Equals, .GetHashCodeo .ToString per assegnare un nome a una proprietà.
Le definizioni di tipi anonimi con almeno una proprietà chiave implementano anche l'interfaccia System.IEquatable<T> , dove T è il tipo del tipo anonimo.
Per altre informazioni sul codice creato dal compilatore e sulla funzionalità dei metodi sottoposti a override, vedere Definizione di tipo anonimo.