Il C# (pronuncia inglese: , come l'espressione see sharp, "vedere nitidamente"Il nome gioca sul fatto che C♯, in inglese e altre lingue, indica la nota musicale Do diesis, un semitono sopra il "C", ovvero il Do (fonte: ). In effetti, il nome del linguaggio andrebbe scritto con il simbolo del diesis, ma in sostituzione si usa il cancelletto per praticità di scrittura (fonte: MSDN, Domande frequenti su Visual C#). In italiano, il gioco di parole viene perso. o anche C sharp, "do diesis" ) è un linguaggio di programmazione multi-paradigma che supporta tutti i concetti della programmazione orientata agli oggetti. Esso è stato sviluppato da Microsoft all'interno dell'iniziativa .NET, e successivamente approvato come standard dalla ECMA (ECMA-334) e ISO (norma ISO/IEC 23270).

La sintassi e struttura del C# prendono spunto da vari linguaggi nati precedentemente, in particolare Delphi, C++, Java e Visual Basic.

Storia del linguaggio Il progettista principale di C# è Anders Hejlsberg, un informatico danese precedentemente coinvolto nello sviluppo dei linguaggi Turbo Pascal e Borland Delphi (attualmente di proprietà di Embarcadero).

È opinione comune che l'ispirazione venne dal linguaggio Java, dato che perfino il suo ideatore James Gosling, nonché Bill Joy di Sun Microsystem, lo definirono una sua imitazione, ma più limitata dal punto di vista dell'affidabilità, della sicurezza e della produttività. Invece, secondo Anders Hejlsberg e Microsoft stessa, la struttura di C# è più vicina a quella del linguaggio C++ di quella di Java.

C# è strettamente legato allo sviluppo di .NET Framework. Infatti gli ingegneri di Microsoft utilizzarono nelle prime fasi della sua stesura un framework chiamato SMC, ovvero Simple Managed C, un sistema utilizzante il linguaggio C in modo gestito o "managed". Nel gennaio 1999, Microsoft mise Anders Hejlsberg a capo di un gruppo di lavoro con il compito di produrre un nuovo linguaggio, chiamato provvisoriamente "Cool", acronimo di "C-like Object Oriented Language" (linguaggio orientato agli oggetti simile a C). Il nome commerciale definitivo divenne C# alla presentazione ufficiale del progetto .NET da parte di Microsoft alla Professional Developers Conference tenutasi nel luglio 2000 a Orlando, quando anche le librerie di classi e il runtime di ASP.NET vennero convertite in linguaggio C#.

Nel tempo C# e Java hanno percorso strade differenti, aumentando complessivamente le differenze reciproche, sebbene ci siano stati anche evidenti casi di reciproco scambio di caratteristiche. Per esempio C#, a differenza di Java, utilizza sin dalla versione 2 la reificazione per generare oggetti generici che possono essere usati come classi, riservando al momento del caricamento della classe in fase di esecuzione la compilazione effettiva del codice. Anche l'implementazione in ambedue i linguaggi dei tipi generici, sebbene concettualmente identica, è stata implementata in maniera piuttosto differente. Invece, il concetto di boxing e unboxing propri di C# sono stati implementati successivamente anche in linguaggio Java.

La versione C# 1.0, basata su .NET Framework 1.0, fu pubblicata commercialmente da Microsoft nel gennaio 2002 con il pacchetto di sviluppo Visual Studio .NET 2002. In seguito sono state pubblicate sino ad oggi nuove versioni del linguaggio e del framework .NET con i pacchetti Microsoft Visual Studio.

Versione C#Data di presentazioneVersione .NETVisual Studio1.0gennaio 20021.0Visual Studio .NET 20022.0novembre 20052.0Visual Studio .NET 20033.0novembre 20072.0/3.5Visual Studio 2008-20104.0aprile 20104.0Visual Studio 20105.0agosto 20124.5Visual Studio 2012-20136.0luglio 20154.6Visual Studio 20157.0marzo 20174.6.2Visual Studio 20177.1agosto 20174.7Visual Studio 2017 Ver. 15.37.2novembre 20174.7.1Visual Studio 2017 Ver. 15.57.3maggio 20184.7.2Visual Studio 2017 Ver. 15.78.0settembre 20194.8Visual Studio 20199.0settembre 20205Visual Studio 201910.0novembre 20216Visual Studio 202211.0novembre 20227Visual Studio 202212.0novembre 20238Visual Studio 2022

Caratteristiche del linguaggio C# è, in un certo senso, il linguaggio che meglio degli altri descrive le linee guida sulle quali ogni programma .NET gira. Infatti è stato creato da Microsoft specificatamente per la programmazione nel framework .NET. I suoi tipi di dati "primitivi" hanno una corrispondenza univoca con i tipi .NET e molte delle sue astrazioni, come classi, interfacce, delegati ed eccezioni, sono particolarmente adatte a gestire il framework .NET. È divenuto quindi il linguaggio ordinario per realizzare software in ambiente Windows.

Definire in forma classica C# come linguaggio interpretato o compilato nel senso classico dei termini è piuttosto complicato. In effetti è ambedue le cose allo stesso tempo. Data la sua stretta integrazione con il framework .NET, i codici sorgente scritti in C# sono normalmente compilati secondo i criteri JIT. In pratica, la trasformazione in codice macchina (ovvero eseguito direttamente dalla CPU) viene compiuta solo all'atto di caricamento ed esecuzione del programma. In prima istanza il codice sorgente viene convertito dal framework in un codice intermedio detto CIL e solo all'esecuzione del programma il CLR specifico per il sistema operativo utilizzato converte il CIL in linguaggio macchina specifico per l'hardware ospite, man mano che viene eseguito. Ciò comporta che l'esecuzione del codice può risultare più lenta alla prima esecuzione diventando poi più veloce. Inoltre, vengono tipicamente svolte durante la compilazione stessa delle ottimizzazioni progressive del codice macchina, producendo così un codice eseguito più velocemente e teoricamente "ottimale" solo dopo alcune esecuzioni complete dello stesso.

Una seconda possibilità è la cosiddetta compilazione Ngen, che permette di convertire tutto il codice CIL in codice macchina in una volta sola. Ciò ha il vantaggio di consentire l'implementazione di ambienti di sviluppo che utilizzino C# in qualunque sistema operativo, una volta implementato il CLR specifico.

La sintassi di base del C# è spesso molto simile o identica a quella dei linguaggi C, C++ e Java. Alcune delle caratteristiche di base sono: I nomi di variabili, funzioni, classi e altri elementi sono sempre sensibili alle minuscole, ovvero "case-sensitive". Ogni specifica dev'essere chiusa dal carattere punto e virgola (;). Gli indici degli elementi di array e matrici sono numerati a partire da 0. Le parentesi graffe ({}) sono usate per raggruppare specifiche. Secondo le consuetudini dei linguaggi orientati agli oggetti, le specifiche sono di regola raggruppate in metodi (ovvero funzioni), i metodi sono raggruppati in classi, e le classi sono raggruppate nei namespace.

Differenze da C e C++ Rispetto a C o a C++ il linguaggio C# presenta varie modifiche, volte principalmente ad evitare errori tipici e ambiguità della programmazione in linguaggio C:

I puntatori possono essere utilizzati solo in particolari blocchi di codice marcati come unsafe. In molte operazioni aritmetiche vengono controllati eventuali overflow. Gli oggetti dinamici non vengono deallocati esplicitamente, ma viene gestita automaticamente e implicitamente dal garbage-collector quando non esistono più riferimenti a tali oggetti. Questo sistema evita i due problemi dei dangling pointer e del memory leak, anche se con una riduzione delle prestazioni. Come in Java è possibile ereditare da una sola classe, diversamente da quanto avviene in C++, ma è possibile implementare un numero indefinito di interfacce. A differenza del C++, non è consentita l'ereditarietà di tipo private. Le sole conversioni implicite consentite sono quelle safe, ovvero che non espongono al rischio di perdita di dati causata dal diverso tipo di dato. Per esempio non sono consentite conversioni implicite fra integer e boolean oppure tra enumeratori ed integer. C# non dispone dei template tipici del C++, ma nella versione 2.0 sono stati introdotti i generic.

Differenze da Java Sebbene C# sia ritenuto simile a Java, esistono alcune importanti differenze fra i due linguaggi. Quella maggiormente visibile è certamente la presenza in C# di molti costrutti, alcuni dei quali chiaramente derivati dal C++, che in Java sono stati deliberatamente vietati. I sostenitori del C# affermano che tutto ciò rende il codice più chiaro, mentre i sostenitori di Java affermano che proprio la presenza di un gran numero di parole-chiave e di regole da ricordare rende il linguaggio più difficile da imparare e utilizzare.

Altre differenze evidenti sono le seguenti: Java utilizza i commenti Javadoc-sintax per generare la documentazione dal codice sorgente, mentre C# utilizza la sintassi XML nei commenti per lo stesso scopo. Quello che in Java è chiamato package, in C# viene chiamato namespace o "spazio di nomi". Un ulteriore livello di organizzazione in C# è costituito dagli assembly, che possono contenere al proprio interno diversi spazi di nomi. Java utilizza un diverso modo per richiamare i metodi costruttori di una classe, ovvero dalla prima riga di un costruttore ne richiama un altro.

Funzionalità introdotte con gli aggiornamenti

Versione 3 Lambda expressions Tipi anonimi LINQ Extension methods

Versione 4 Pseudo tipo dynamic Covarianza e Controvarianza nei tipi di parametri per interfacce generiche e delegati Specifica ref opzionale per l'uso di COM Parametri opzionali e nomi di argomenti Indicizzatori di Proprietà (riconosciuti, ma non utilizzati dagli oggetti in C#)

Versione 5

Metodi asincroni Attributi Caller Info

Versione 6

Servizio compilatore Importazione di membri di tipo statico nel namespace Filtri di eccezione Await nei blocchi catch/finally Inizializzatori di proprietà automatici Valori di default per proprietà di tipo getter esclusivo Membri expression-bodied Propagatore di null Interpolazione stringhe Operatore nameof Inizializzatore di dizionario

Versione 7

Binary literals Decostruttori Separatori di cifra Funzioni locali Tipo switch Ref return Tuple con nome Out var Pattern Matching Ritorni asincroni arbitrari Records Get e Set nelle definizioni di espressioni Costruttori e finalizzatori nelle definizioni di espressioni

Versione 8

Nullable reference types Membri di interfaccia di default Flussi asincroni Switch expressions Funzioni statiche locali Membri struct di sola lettura Miglioramento delle stringhe verbatim interpolate Records migliorati Indici ed intervalli Assegnamento con null-coalescing

Versione 9

Dichiarazioni di primo livello Miglioramenti della corrispondenza dei modelli I setter solo Init Numeri interi di dimensioni native Puntatori a funzione Funzioni static anonime Parametri di scarto di Lambda Records migliorati Attributi su funzioni locali Nuove funzionalità per metodi parziali

Esempi Hello world! Il seguente esempio visualizza il testo "Hello world" su console.

using System;

class HelloWorldApp

public static void Main(string[] args) // punto d'ingresso del programma

Console.WriteLine("Hello World"); Console.ReadLine ();

Invece il seguente esempio stampa il testo "Hello world" in una Message Box.

using System.Windows.Forms;

class HelloWorldApp

public static void Main()

MessageBox.Show("Hello World");

Definizione di classe Il seguente esempio definisce una classe di nome Persona che espone una proprietà Nome il cui valore viene memorizzato nella variabile mNome:

using System; namespace Program { class Persona

private string mNome;//se non specifico "private" non ci sono differenze, perché è sottinteso.

public string Nome

get { return mNome; } set { mNome = value; }

Lo stesso esempio si può scrivere in una forma equivalente, utilizzando la sintassi delle Automatic Properties introdotta con la versione 3.0:

using System; class Persona

public string Nome { get; set; }