Condividi tramite


Tipi anonimi (Guida per programmatori C#)

I tipi anonimi offrono un modo pratico per incapsulare un set di proprietà di sola lettura in un singolo oggetto senza definire prima un tipo denominato. Il compilatore genera un nome di tipo in fase di compilazione a cui non è possibile accedere nel codice sorgente. Il compilatore deduce il tipo di ogni proprietà.

Creare tipi anonimi usando l'operatore new insieme a un inizializzatore di oggetto. L'esempio seguente mostra un tipo anonimo inizializzato con due proprietà e NameAge:

var person = new { Name = "Alice", Age = 30 };
Console.WriteLine($"{person.Name} is {person.Age} years old.");
// Output:
// Alice is 30 years old.

Nomi di proprietà dedotti

È possibile specificare i nomi delle proprietà in modo esplicito usando la Name = value sintassi . Quando si inizializza un tipo anonimo con una variabile o un'espressione di accesso ai membri, il compilatore deduce il nome della proprietà da tale espressione:

string productName = "Laptop";
decimal price = 999.99m;
var product = new { productName, price };
Console.WriteLine($"{product.productName}: {product.price:C}");
// Output:
// Laptop: $999.99

Nell'esempio precedente il compilatore deduce productName e price come nomi di proprietà dai nomi delle variabili usati nell'inizializzatore.

Dichiarare tipi anonimi con var

Poiché il compilatore genera il nome del tipo e non è possibile accedervi nel codice sorgente, è necessario usare var per dichiarare la variabile locale. Non è possibile specificare il nome del tipo in modo esplicito:

// You must use var — you can't write a named type here.
var person = new { Name = "Alice", Age = 30 };

Usare tipi anonimi nelle query LINQ

I tipi anonimi vengono visualizzati più spesso nella clausola di un'espressione select di query, in cui proiettano un subset di proprietà da ogni elemento di origine:

var words = new[] { "apple", "blueberry", "cherry" };

var results = words.Select(w => new { Word = w, Length = w.Length });

foreach (var item in results)
{
    Console.WriteLine($"{item.Word} has {item.Length} letters.");
}
// Output:
// apple has 5 letters.
// blueberry has 9 letters.
// cherry has 6 letters.

Uguaglianza

Due istanze di tipo anonimo con gli stessi nomi di proprietà e tipi nello stesso ordine condividono lo stesso tipo generato dal compilatore. Il compilatore esegue l'override Equals e GetHashCode in modo che l'uguaglianza confronta i valori delle proprietà anziché l'identità di riferimento:

var a = new { Name = "Alice", Age = 30 };
var b = new { Name = "Alice", Age = 30 };
var c = new { Name = "Bob", Age = 25 };

Console.WriteLine(a.Equals(b));  // True
Console.WriteLine(a.Equals(c));  // False

Tipi anonimi annidati

I tipi anonimi possono contenere altri tipi anonimi come valori di proprietà:

var order = new
{
    OrderId = 1,
    Customer = new { Name = "Alice", City = "Seattle" },
    Total = 150.00m
};
Console.WriteLine($"Order {order.OrderId} for {order.Customer.Name} in {order.Customer.City}");
// Output:
// Order 1 for Alice in Seattle

Caratteristiche

I tipi anonimi presentano le caratteristiche seguenti:

  • Il compilatore li genera come internal sealed class tipi che derivano da Object.
  • Tutte le proprietà sono public di sola lettura.
  • I tipi anonimi supportano with espressioni per la mutazione non distruttiva.
  • Il compilatore genera sostituzioni basate su valori Equals, GetHashCode e ToString.
  • I tipi anonimi supportano alberi delle espressioni, mentre le tuple non lo sono.

Limitazioni

I tipi anonimi presentano diverse limitazioni:

  • Non è possibile usarli come tipi restituiti dal metodo, parametri del metodo o tipi di campo perché non è possibile denominare il tipo.
  • Sono limitati all'ambito di visibilità del metodo in cui vengono dichiarati.
  • Non è possibile aggiungere metodi, eventi o operatori personalizzati.
  • Le proprietà sono sempre di sola lettura; I tipi anonimi non supportano proprietà modificabili.

Quando usare invece le tuple

Per la maggior parte del nuovo codice, è consigliabile usare tuple anziché tipi anonimi. Come tipi di valore, le tuple offrono prestazioni migliori. Forniscono anche il supporto della decostruzione e una sintassi più flessibile. I tipi anonimi rimangono la scelta migliore quando è necessario il supporto dell'albero delle espressioni o la semantica di tipo riferimento. Per un confronto dettagliato, vedere Scelta tra tipi anonimi e tuple.

Vedere anche