Anonymous type di C# 3.0

Cristian Civera

di Cristian Civera, in .NET 3.0, venerdì 4 gennaio 2008 ore 14.21

Giocando con LINQ avrete senz'altro usato gli anonymous type: quei tipi creati al volo per contenere varie informazioni. Poniamo questo semplice esempio:

var v = new {Language = "IT", Age=30};

Prima di tutto, v è visibile solo all'interno dello stack in cui l'abbiamo dichiarato. Quindi all'interno di una funzione o metodo, ma mai a livello di classe. Possiamo anche ritornarlo come valore da una funzione, ma potremmo limitarci a ritornare un tipo object generico e non potremmo fare riferimento al nome del tipo, facendo cast o quant'altro (se non via reflection, bleah bleah). Quindi ques'ultima opzione è fortemente sconsigliata.

Quando compiliamo, viene automaticamente generata una classe internal sealed dal nome f__AnonymousType[numero] sul namespace root. La classe eredita da Object definisce n proprietà e n campi per memorizzare i valori e dispone di un costruttore che accetta come parametri i valori da impostare sulle proprietà. Non c'è modo di cambiarne visibilità ai tipi o ai membri, ne di rendere in sola lettura le proprietà. Questa classe ha la particolarità di essere generica, nel senso che i tipi string e int delle proprietà Language e Age del nostro esempio, sono generici. Questo per evitare di creare copie della medesima classe. Quindi se utiliziamo nel medesimo assembly un anonymous type simile:

var v = new {Language = 1, Age=3d};

verrà utilizzata la medesima classe autogenerata, ma con generics argument diversi: int e double.

Tale classe inoltre sovrascrive ToString per mostrare facilmente il contenuto, Equals e GetHashCode così da rendere comparabile il tipo quando viene utilizzato, per esempio da LINQ To Objects:

[DebuggerHidden]  
public override string ToString()  
{  
    StringBuilder builder = new StringBuilder();  
    builder.Append("{ Language = ");  
    builder.Append(this.<Language>i__Field);  
    builder.Append(", Age = ");  
    builder.Append(this.<Age>i__Field);  
    builder.Append(" }");  
    return builder.ToString();  
}  
  
[DebuggerHidden]  
public override int GetHashCode()  
{  
    int num = 0x5b485bf4; // Numero casuale  
    num = (-1521134295 * num) + EqualityComparer<<Language>j__TPar>.Default.GetHashCode(this.<Language>i__Field);  
    return ((-1521134295 * num) + EqualityComparer<<Age>j__TPar>.Default.GetHashCode(this.<Age>i__Field));  
}  
  
[DebuggerHidden]  
public override bool Equals(object value)  
{  
    var type = value as <>f__AnonymousType0<<Language>j__TPar, <Age>j__TPar>;  
    return (((type != null) && EqualityComparer<<Language>j__TPar>.Default.Equals(this.<Language>i__Field, type.<Language>i__Field)) && EqualityComparer<<Age>j__TPar>.Default.Equals(this.<Age>i__Field, type.<Age>i__Field));  
}

Sono interessanti l'uso di DebuggerHidden per evitare di far vedere dal debugger tali metodi e l'uso di EqualityComparer.Default per ottenere l'hashcode o comparare i tipi primitivi utilizzati. EqualityComparer.Default restituisce un IEqualityComparer<T> (fondamentale in LINQ) a seconda che il tipo implementi IEquatable<T>, sia nullabile o come ultima spiaggia, sovrascriva Equals e GetHashCode. Per comparare le stringhe (utile sempre in LINQ) abbiamo a disposizione la classe StringComparer che permette diversi modi di comparazione delle stringhe: CurrentCulture, CurrentCultureIgnoreCase, InvariantCulture, InvariantCultureIgnoreCase, Ordinal, OrdinalIgnoreCase.

Commenti

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.



Segnala su: Facebook MSDN Social Twitter Segnalo Wikio Diggita Technorati Stumbleupon Google Yahoo FriendFeed Delicious Furl

Nella stessa categoria
I più letti del mese
TagCloud
.NET Framework, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5, .NET Framework 4.0, ADO.NET Entity Framework, AJAX, Architettura, ASP, ASP.NET, ASP.NET 2.0, ASP.NET 2.0 per tutti, ASP.NET 4.0, ASPItalia.com, Custom Control, Databinding, Datagrid, HttpRuntime, IIS, Javascript, LINQ, LINQ to Entities, LINQ to SQL, Media Center, Microsoft Expression, Object Oriented Programming, Off Topic, PDC 2008, Silverlight, Silverlight - animazioni, Silverlight 2.0, Silverlight 3.0, User Control, Visual Studio, Windows 7, Windows CardSpace, Windows Client, Windows Communication Foundation, Windows Live Services, Windows Presentation Foundation, Windows Server, Windows Vista, Windows Workflow Foundation, XAML, XBox 360, XHTML, XML, XPS, XSLT
BLOG INFO
  • 199 post, 86 commenti, 42 trackback
  • Feed blog e contenuti tecnici: RSS
  • Feed blog: RSS Atom
IN EVIDENZA