C sharp
Rakenne

C# on korkeamman tasoinen, olioperusteinen, vahvasti tyypitetty kieli. Vahva tyypitys tarkoittaa, että muuttujilla on oltava aina jokin tietotyyppi, esimerkiksi kokonaisluku, luokka tai merkkijono. (C# kuitenkin mahdollistaa var-sanan käytön, kun tyyppi on niin lukijalle kuin kääntäjällekin selvä.) Korkea abstraktiotaso ilmenee erityisesti siinä, että muistinhallinta on automatisoitu eli automaattinen roskienkeräys vapauttaa muistia käyttöön sitä mukaa, kun objekti ei ole enää ohjelman saavutettavissa.
C# muodostuu nimiavaruuksista (namespace), näissä olevista tyypeistä (esim. class) ja näissä määritellyistä jäsenistä, kuten datasta, funktioista, perustyypistä, rajapinnoista ja operaattoritoteutuksista. Tyyppien avulla luodaan (new) muuttujia, jotka sisältävät referenssin yhteen (arvotyyppi) tai useampaan (referenssityyppi) objektiin.
C#-tyyppijärjestelmä on yhtenäinen ja sen avulla voidaan määritellä
yksinkertaiset arvotyypit (esim. int), jotka sisältävät numeron, merkin tai totuusarvon
null-arvotyypit (esim. int?) jotka sisältävät jonkin arvotyypin lisäksi null-arvon
enum-arvotyypit (enum E {...}), jotka sisältävät joukon vakioarvoja
tuple-arvotyypit ((T1, T2, ...)), jotka sisältävät yksinkertaisen joukon arvotyyppejä
struct-arvotyypit (struct E {...}), jotka sisältävät monimutkaisemman joukon arvotyyppejä
taulukkotyypit (esim. int[][])
luokkatyypit (class C {...}, string), jotka sisältävät dataa ja funktioita
rajapintatyypit (interface I {...})
delegaattityypit (delegate int D(...)), jotka sisältävät referenssin tiettyyn itsenäisesti käytettävään funktioon
record-tyypit (record struct tai record class), jotka sisältävät arvojen lisäksi tiettyjä synteettisiä jäseniä.
Tyypin jäseniä voivat olla
kentät eli tyypin sisäiset muuttujat
vakiot eli muuttujat, joiden arvo vakioidaan käännöksen aikana
ominaisuudet, joka lukevat ja kirjoittavat arvoja
metodit, jotka määrittelevät luokan toiminnot
alustaja, joka luo tyypistä uuden objektin
indeksoija, joka lukee ja kirjoittaa indeksiarvoja
tapahtumat, joka ovat kenttiä, joiden muutoksiin käyttäjä reagoi tapahtumankäsittelijöillä
operaattorit, jotka määrittelevät matemaattisten operaattoreiden (esim. == tai +) toiminnan ja
finalisoija, joka vapauttaa resursseja roskienkeräyksen yhteydessä (määritellään harvoin).
Luokka- ja rajapintatyyppejä organisoidaan perimähierarkioiksi niin, että kaikkien luokkien käyttämät jäsenet (data ja funktiot) löytyvät hierarkian abstrakteimmasta luokasta ja uudet luokat lisäävät yhä spesifisempiä jäseniä tarpeen mukaan. Tällöin luokkatyyppi määritellään tyylillä class AliTyyppi : Perustyyppi {...} tai interface Alityyppi : PerustyyppiI, PerustyyppiII {...}.
Kaikkia ylätyypin jäseniä ei kuitenkaan ole pakollista periä sellaisenaan (polyformia). Jos esim. ylätyypin metodi on määritelty avainsanalla virtual, alatyyppi voi määritellä metodin uudelleen override-avainsanalla. Alatyyppi voi myös piilottaa ylätyypin jäsenen käyttämällä new-avainsanaa tai keskeyttää virtuaalisen jäsenen periytymisen sealed-avainsanalla.
Luokka-, tietue-, rajapinta- ja delegaattityypit hyväksyvät myös parametreja, mikä mahdollistaa geneeristen tyyppien luomisen. Tällöin esim. luokkatyyppi määritellään tyylillä class Nimi<Tyyppi, Tyyppi> {...}.
Tyyppien jäsenien näkyvyyttä ja muutettavuutta ohjelmissa säädellään avainsanoilla kuten public, private, protected, static, readonly, const, override, abstract, virtual ja sealed.
Lausekkeisiin kuuluvat muun muassa
valintalausekkeet if ja switch
toistolausekkeet for, while, do ja foreach
siirtolausekkeet break, continue, goto, throw, return ja yield
poikkeuksien hallinnan try, catch ja finally
alustamisen new
rinnakkaislaskennan async ja await sekä
parametrimääreet ref, out, in ja params.
Mainittavia operaattoreita ovat esim. ??-operaattori, joka palauttaa jälkimmäisen lausekkeen arvon edellisen ollessa null, ja ns. Elvis-operaattori ehto ? seuraus : vaihtoehto.
C# tukee suoraan myös funktionaalisia tekniikoita, vaikka nämäkin perustuvat tyyppeihin. Delegaattityypit mahdollistavat itsenäiset funktiot. Hahmonsovitus onnistuu käyttämällä is ja switch lausekkeita. Alaviiva-muuttuja ja objekti-dekonstruktio mahdollistavat joustavan sijoittamisen funktioista uusiin muuttujiin. Lambda-lausekkeet ovat kielessä muotoa esim. (double x) => x * 2.0. Ennen kaikkea LINQ lisää kieleen hyvin deklaratiivisen menetelmän poimia tietoa datarakenteista lausekkeiden kuten from..in, where, orderby, group..by..into, join..in..on..equals, select..into ja let avulla. (LINQ toimii siis kuin SQL tietokannoissa.)
Lisäksi kieleen kuuluvat attribuutit, jotka ovat tapa liittää tyyppeihin metadataa. Nämä merkitään ennen haluttua tyyppiä esim. [Author("E. Sukunimi")].
Lähdetiedostot (.cs) käännetään yhdeksi ns. assembly-tiedostoksi (.dll tai .exe), joka sisältää välimuotoista koodia ja metadataa, mikä taas käännetään tarvittaessa prosessorille sopivalle konekielelle. C#-ohjelma aloittaa ajon ylimmän tason lausekkeesta tai Main-metodista.