Around and About .NET World

Il blog di Marco Minerva
posts - 1612, comments - 2154, trackbacks - 2144

My Links

News


Curriculum Vitae (ITA)

Curriculum Vitae (ENG)

Contattami su Live Messenger:


MCTS: Windows, Web, Distributed Applications & SQL Server

MCPD: Enterprise Applications

Tag Cloud

Archives

Post Categories

Links

Attenzione all'inferenza dei tipi di .NET 3.5

Una delle novità maggiormente decantate di .NET 3.5 è l'inferenza dei tipi, ovvero la possibilità di determinare staticamente, a tempo di compilazione, il tipo di una variabile in base al suo contenuto. Tutto quello che serve, per utilizzarla, è indicare var come tipo di dato: quando incontra questa parola chiave, il compilatore sa che deve analizzare i dati memorizzati nella variabile per determinarne il tipo. Si tratta di una funzionalità molto comoda e che, quando si utilizza LINQ, spesso permette di evitare la creazione di classi specializzate per contenere i risultati delle interrogazioni, consentendo comunque di avere un accesso tipizzato alle informazioni.

Bisogna comunque stare attenti quando si utilizza la parola chiave var. In alcuni casi, infatti, si potrebbero ottenere risultati diversi da quelli che ci si aspettano. Consideriamo il seguente esempio:

 

short s = 4; var i = s + 1; Console.WriteLine("Il tipo della variabile i è: " + i.GetType().ToString());

Poiché la variabile s è di tipo short (System.Int16), si potrebbe pensare che il risultato di s + 1 (ovvero 5) sia anch'esso di questo tipo... In realtà non è così: poiché, per impostazione predefinita, l'operatore + applicato a due dati numerici interi restituisce un int, la variabile i sarà di quest'ultimo tipo (d'altra parte, se al posto di var i =... si fosse usato short i =..., si sarebbe ottenuto un errore di compilazione).

Attenzione, quindi: quando si utilizza l'inferenza di tipi, è bene verificare che tutto funzioni come previsto.

Technorati Tags: , ,

Print | posted on sabato 15 novembre 2008 17.52 | Filed Under [ C# Orcas & .NET 3.5 ]

Feedback

Gravatar

# re: Attenzione all'inferenza dei tipi di .NET 3.5

Per essere precisi... il problema è dovuto al fatto che si somma uno short (Int16) ad un int (Int32), in quanto il numero "1" viene considerato di default "int" dal compilatore.
Per memorizzare il risultato viene quindi utilizzato un Int32 (intero più piccolo in grado di contenere la somma tra un Int32 e un Int16).

Se scrivessimo:

var i = s + 1s;

indicheremmo al compilatore che l'1 deve essere considerato di tipo short, per cui i dovrebbe (in teoria, ma non ho provato) venire tipizzata correttamente.
15/11/2008 18.35 | neronotte
Gravatar

# re: Attenzione all'inferenza dei tipi di .NET 3.5

Hum... La sintassi che hai scritto, con la "s" dopo il numero 1, non mi sembra corretta... Comunque, le cose non stanno come dici tu, infatti provando a scrivere:

short s = 4;
short s2 = 1;
var i = s + s2;

i viene comunque tipizzata con int... L'unico modo perché essa assuma il valore short, è fare il cast del risultato, ovvero:

short s = 4;
short s2 = 1;
var i = (short)(s + s2);
15/11/2008 18.39 | marco.minerva@gmail.com
Gravatar

# re: Attenzione all'inferenza dei tipi di .NET 3.5

Questa promozione automatica da short a int e' conforme a alla "C# Language Specification" [*], para. 4.1.5 in particolare, di cui quoto una parte qui:

<< ...

The integral-type unary and binary operators always operate with signed 32-bit precision, unsigned 32-bit precision, signed 64-bit precision, or unsigned 64-bit precision:

-- For the unary + and ~ operators, the operand is converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T.

-- For the unary – operator, the operand is converted to type T, where T is the first of int and long that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T. The unary – operator cannot be applied to operands of type ulong.

-- For the binary +, –, *, /, %, &, ^, |, ==, !=, >, <, >=, and <= operators, the operands are converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of both operands. The operation is then performed using the precision of type T, and the type of the result is T (or bool for the relational operators). It is not permitted for one operand to be of type long and the other to be of type ulong with the binary operators.

-- For the binary << and >> operators, the left operand is converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T.

... >>

Questo comportamento, se non sbaglio, ha reminiscenze di C/C++, dove la promozione (ed eventuale depromozione, ad esempio nel caso 'i' sopra fosse dichiarata short) e' dovuta al fatto che i calcoli, dietro le quinte, vengono comunque fatti almeno alla precisione dei registri della CPU.

-LV

[*] msdn.microsoft.com/en-gb/vcsharp/aa336809.aspx
16/11/2008 8.00 | LudovicoVan
Gravatar

# re: Attenzione all'inferenza dei tipi di .NET 3.5

P.S. Questo fatto e' sicuramente importante in C/C++, dove un algoritmo definito in termini di int e' molto piu' performante dello stesso algoritmo definito in termini di short/byte/char, per via appunto delle conversioni/deconversioni implicite. Non saprei se lo stesso impatto si ha con C#, che e' un linguaggio molto piu' di alto livello: visto che il comportamento specificato e' lo stesso, presumo di si', ma occorrerebbe fare una prova (a meno che qualcuno non conosca gia' la risposta).

-LV
16/11/2008 8.09 | LudovicoVan
Comments have been closed on this topic.

Powered by: