Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

C# - Fondamenti del linguaggio C#

C#

Il CLR, l'IL e il JIT

  • I programmi creati con C#, possono essere eseguiti solo su macchine che hanno il .NET Common Language Runtime (CLR). In caso contrario, semplicemente non vengono eseguiti.
  • Il beneficio principale è la portabilità. Programmi creati con altri linguaggi, per poter essere eseguiti su macchine Windows e Linux, devono essere compilati con due compilatori diversi. Un programma compilato con C# produce un file in Intermediate Language (IL) che può essere copiato da una macchina all’altra. Esso non è eseguibile direttamente ma tramite il CLR.
  • Il CLR quindi compila solo la parte di codice che deve essere eseguita e l’esito della compilazione è il Just In Time (JIT) o jitting.
  • La versione del CLR non va di pari passo con quella del C#, né con quella del Framework. Al momento esistono le sole versioni 2.0 e 4.0. Per trovare le versioni installate sulla macchina, dal prompt dei comandi di Visual Studio, dare il comando clrver. Il risultato dovrebbe essere:

Versions installed on the machine:
v2.0.50727
v4.0.30319

  • L’esecuzione di un programma C# è inizialmente più lenta di un programma scritto per esempio in C++ in quanto occorre compilarlo in linguaggio macchina, ma una volta che una parte di codice è stata compilata, la sua esecuzione è veloce come quella in altri linguaggi.

Note sulla sintassi
  • Il C# è case sensitive.
  • Le variabili vanno sempre dichiarate e inizializzate. Il primo carattere può essere una lettera, l'underscore ("_") oppure l'at ("@").
  • Terminare le istruzioni con ";".

Tipi di dati
  • Nella tabella seguente vengono riassunti i tipi di dati primitivi.

Tipo di dato C#

Tipo di dato .NET

Dim. (byte)

Val. minimo

Val. massimo

sbyte

System.Sbyte

1

-128

127

byte

System.Byte

1

0

255

short

System.Int16

2

-32,768

32,767

ushort

System.UInt16

2

0

65,535

int

System.Int32

4

-2,147,483,648

2,147,483,647

uint

System.UInt32

4

0

4,294,967,295

long

System.Int64

8

-9,223,372,036,854,775,808

9,223,372,036,854,775,807

ulong

System.UInt64

8

0

18,446,744,073,709,551,615

char

System.Char

2

0

65,635

float

System.Single

4

-3.4e38

-1.5e-45

     

1.5e-45

3.4e38

double

System.Double

8

-1.7e308

-5.0e-324

     

5.0e-324

1.7e308

decimal

System.Decimal

16

+/-1.0e-28

+/-7.9e28

bool

System.Boolean

1

false (0)

true (1)

  • I tipi di dati sbyte, byte, short, ushort, int, uint, long e ulong, sono adatti a contenere numeri interi.
  • I tipi di dati float, double e decimal, sono adatti a contenere numeri decimali. Il float e il double memorizzano numeri nel formato mantissa e esponente a base 2, mentre il decimal memorizza numeri nel formato mantissa e esponente a base 10.
  • I valori con virgole sono sempre double; i valori senza virgole sono sempre int. Questa regola vale sempre eccetto nel caso che dopo il numero sia indicato un suffisso.
  • Il float ha una precisione di circa 7 cifre decimali. Per utilizzarlo deve essere seguito da 'F' o 'f':

   float x = 3.5F // oppure
   float x = 3.5f


  • Il double ha una precisione da 14 a 16 cifre decimali. Per utilizzarlo deve essere seguito da 'D' o 'd' o niente perché un decimale per default è un double:

   double x = 3.1415926587412536D // oppure
   double x = 3.1415926587412536d


  • Il decimal ha una precisione da 28 a 29 cifre decimali. Per utilizzarlo deve essere seguito da 'M' o 'm':

   decimal valore = 1234.5M // oppure
   decimal valore = 1234.5m


  • Elenco di tutti i suffissi:
       - int: nessuno
       - uint: u, U
       - long: l, L
       - ulong: ul, Ul, uL, UL, lu, Lu, lU, LU
       - float: f, F
       - double: nessuno, d, D
       - decimal: m, M

Operatori e operazioni
  • Nella tabella seguente ci sono gli operatori:

Operatore

Descrizione

=

Assegnazione

+, -, *, /

Operatori aritmetici

%

'Resto' della divisione

+

Concatena stringhe

++

Incrementa, può essere prefisso o postfisso

--

Decrementa, può essere prefisso o postfisso

==

Uguaglianza

!= Disuguaglianza
<, <=, >, >= Minore, minore o uguale, maggiore, maggiore o uguale
&, && Operatori logici AND e AND corto circuito
|, || Operatori logici OR e OR corto circuito
^ Operatore logico XOR
op1 ? op2 : op3 Operatore ternario equivalente a:
   if(op1)
       return op2;
   else
       return op3;
?? Operatore null coalescing; per esempio:
   var ret = exp1 ?? exp2 ?? expDefault
assegna a ret la prima espressione non nulla tra exp1, exp2 e expDefault
?. Operatore null conditional; per esempio:
   int? len=str?.Length;
assegna a variabile len (che nullable, cioè può assumere un valore nullo) la lunghezza della stringa str, solo se non nulla
nameof() Operatore introdotto in C#6, restituisce il nome di un elemento di codice (variabile, tipo, membre, ...)
is L'operatore (restituisce true o false) verifica se una variabile è di un certo tipo o se è convertibile in un certo tipo.
Esempi:
   public class c1 { }
   public class c2 : c1 { }
   c1 object1 = new c1();
   c2 object2 = new c2();
   Console.WriteLine(object1 is c1);   // True
   Console.WriteLine(object2 is c2);   // True
   Console.WriteLine(object1 is c2);   // False
   Console.WriteLine(object2 is c1);   // True
as L'operatore permette la conversione di un oggetto in un tipo se la conversione è possibile, altrimenti restituisce un null.
Esempio (con le stesse classi definite sopra):
   c2 object2 = object1 as c2;

Precedenza degli operatori
  • Nella tabella seguente vengono riassunte le precedenze tra gli operatori.

Categoria

Operatore

Descrizione

Primari

()

Override con precedenza

 

++

Pre/Post-incremento

 

--

Pre/Post-decremento

Unari

!

Not logico

 

+

Addizione

 

-

Sottrazione

Moltiplicativi

*

Moltiplicazione

 

/

Divisione

 

%

Resto della divisione

Addizionali

+

Addizione

 

-

Sottrazione

Relazionari

<

Minore

 

<=

Minore o uguale

 

>

Maggiore

 

>=

Maggiore o uguale

Di uguaglianza/disuguaglianza

==

Uguale

 

!=

Non uguale

And logico

& e &&

AND logico

Or logico

| e ||

OR logico

Xor logico

^

XOR logico

Assegnazione

=

Assegnazione

Caratteri di escape

  • Nella tabella seguente sono elencati i caratteri di escape.

Carattere

Descrizione

Carattere Unicode

\a

Segnale sonoro (Alert)

0x0007

\r

Ritorno a capo (carriege return)

0c00D

\n

Nuova linea (new line)

0x000A

\f

Avanzamento pagina (form feed)

0x000C

\t

Tabulazione orizzontale

0x0009

\v

Tabulazione verticale

0x000B

\b

Backspace

0x0008

\\

Backslash

0x005C

\'

Apice singolo

0x0027

\"

Apice doppio

0x0022

\0

Null

0x0000

Le versioni del Framework

  • Nella tabella seguente sono elencate le versioni Framework e del C# con le caratteristiche introdotte.

Anno

Versione .Net

Versione C#

Caratteristiche introdotte

2002

.Net 1

C# 1

Classi, Struct, Interfacce, Eventi, Proprietà, Delegati
Operatori ed espressioni, Istruzioni, .Attributes (Attributi)

2003

.Net 1.1

C# 1.2

2005

.Net 2

C# 2

Generics, Tipi parziali, Metodi anonimi, Tipi valore nullable, Iterators, Covarianza e controvarianza.

2006

.Net 3

N/A

2007

.Net 3.5

C# 3

Proprietà implementate automaticamente, Tipi anonimi, Espressioni di query, Espressioni lambda, Alberi delle espressioni, Metodi di estensione, Variabili locali tipizzate in modo implicito, Metodi parziali, Inizializzatori di oggetto e di raccolta.

2010

.Net 4

C# 4

Associazione dinamica, Argomenti denominati/facoltativi, Covarianti e controvarianti generiche, Tipi di interoperabilità incorporati.
2012 .Net 4.5 C# 5
2013
.Net 4.5.1
.Net 4.5.2
C# 5
Membri asincroni, Attributi informativi sul chiamante.
2015 .Net 4.6
.Net 4.6.1
.Net 4.6.2
C# 6
Importazioni statiche, Filtri eccezioni, Inizializzatori di proprietà automatiche, Membri con corpo di espressione, Propagazione Null, Interpolazione di stringhe, Operatore nameof.
2017 .Net 4.7
.Net 4.7.1
C# 7
C# 7.1
C# 7.2
C# 7.3
Variabili out, Tuple e decostruzione, Criteri di ricerca, Funzioni locali, Membri di espressioni corpo espansi, Variabili locali e valori restituiti per riferimento.

.Net Core C# 8
Membri di sola lettura, Metodi di interfaccia predefiniti, Miglioramenti dei criteri di ricerca,
Uso delle dichiarazioni, Funzioni locali statiche,
Struct ref Disposable, Tipi riferimento nullable,
Flussi asincroni, Indici e intervalli, Assegnazione null-coalescing, Tipi costruiti non gestiti,
Stackalloc nelle espressioni annidate,
Miglioramento delle stringhe verbatim interpolate.

.Net 5 C# 9
Record, Setter di sola inizializzazione,
Istruzioni di primo livello, Miglioramenti dei criteri di ricerca, Prestazioni e interoperabilità, Adattare e completare le funzionalità, Supporto per generatori di codice.


C# 10
Struct di record, Miglioramenti dei tipi di struttura,
Gestori di stringhe interpolate, Direttive,
Dichiarazione dello spazio dei nomi con ambito file,
Modelli di proprietà estese, Miglioramenti alle espressioni lambda, Consenti stringhe interpolate
I tipi di record possono bloccare, Assegnazione definita migliorata, Consentire sia l'assegnazione che la dichiarazione nella stessa decostruzione,
Consenti attributo nei metodi, Attributo CallerArgumentExpression, Pragma avanzato.

Debug dei programmi

  • Quando si programma è utile scrivere delle informazioni (valori di variabili per esempio) da qualche parte per verificare se il programma si comporta come progettato.
  • Si può utilizzare la classe 'Debug' contenuta in 'System.Diagnostics'.
  • Tra i vari metodi, i più interessanti sono 'WriteLine' (con due overload) e 'WriteLineIf'.

   using System.Diagnostics;

   for (int i = 0; i < 10; i++)
   {
       
Debug.WriteLine("Debug Ciclo numero " + i);
       
Debug.WriteLine("Debug Ciclo numero " + i, "Categoria");
       
Debug.WriteLineIf(i % 2 == 0, i);
   }


  • L'esempio precedente mostra alcuni utilizzi della classe Debug.
  • Le stringhe sono scritte nella finestra 'Output'.
  • Output della prima riga:

Debug Ciclo numero 0
...
Debug Ciclo numero 9

  • Output della seconda riga:

Categoria: Debug Ciclo numero 0
...
Categoria: Debug Ciclo numero 9

  • Output della terza riga:

0
2
4
6
8

© 2022 Carlo Vecchio
Torna ai contenuti