C# (lausutaan ”si sharp”) on Microsoftin kehittämä yleiskäyttöinen, korkean tason ohjelmointikieli, joka tukee useita ohjelmointiparadigmoja, kuten oliopohjaista, imperatiivista, funktionaalista, geneeristä ja komponenttipohjaista ohjelmointia. Kieli on olennainen osa .NET-ekosysteemiä ja sitä käytetään laajasti sekä Microsoftin omissa että avoimen lähdekoodin toteutuksissa, kuten .NET-, Mono- ja Unity-ympäristöissä.
Kielessä on staattinen ja vahva tyypitys, automaattinen muistinhallinta roskienkeruun avulla sekä suoritusmalli, jossa lähdekoodi käännetään ensin välitasokoodiksi (Common Intermediate Language, CIL) ja suoritetaan sen jälkeen tyypillisesti ajonaikaisen kääntämisen (just-in-time, JIT) tai ennen ajoa tehtävän kääntämisen (ahead-of-time, AOT) kautta. Kieli on suunniteltu moderniksi ja turvalliseksi vaihtoehdoksi C-suvun kielille, säilyttäen samalla monia C++- ja Java-kielistä tuttuja syntaksisia elementtejä.
C#:llä kehitetään muun muassa yrityssovelluksia, verkkosovelluksia ja -palveluita, pilvipohjaisia ratkaisuja (Microsoft Azure), työpöytä- ja mobiilisovelluksia (.NET MAUI), pelejä (Unity), selainpohjaisia sovelluksia (Blazor) sekä data- ja tekoälysovelluksia (ML.NET). Uusin vakaa versio on C# 14.0, joka julkaistiin marraskuussa 2025 osana .NET 10 -alustaa.
Historia Tausta ja synty 1990-luvun lopussa Microsoft aloitti .NET-hankkeen yhtenäisen sovelluskehitysalustan luomiseksi. Hankkeen puitteissa aloitettiin uuden C#-ohjelmointikielen kehitys pääsuunnittelija Anders Hejlsbergin johdolla. Kieli esiteltiin julkisesti vuonna 2000 osana .NET Framework -alustaa ja Visual Studio .NET -kehitysympäristöä.
Microsoft toimitti kielen ja siihen liittyvän Common Language Infrastructure (CLI) -spesifikaation standardoitavaksi Ecma Internationalille. Kielestä tuli Ecma-standardi ECMA-334 joulukuussa 2002 ja myöhemmin ISO/IEC-standardi ISO/IEC 23270. Standardointi helpotti vaihtoehtoisten toteutusten, kuten avoimen lähdekoodin Mono-projektin, kehittämistä.
Kielen nimi ”C#” viittaa ohjelmointikielten C-sukuun ja musiikin korotettuun säveleen (C♯). Virallisissa yhteyksissä nimi kirjoitetaan risuaitamerkin (#) kanssa ECMA-standardin mukaisesti (”C#”).
Varhaiset versiot (1.0–4.0) Ensimmäinen C#-versio (1.0) julkaistiin vuonna 2002 osana .NET Framework 1.0 -alustaa ja Visual Studio .NET -kehitysympäristöä. Versio tarjosi oliopohjaiset perusrakenteet, kuten luokat, rakenteet, rajapinnat, poikkeuskäsittelyn, ominaisuudet, tapahtumat ja delegaatit, sekä erottelun viite- ja arvotyyppien välillä. Kieli perustui automaattiseen roskienkeruuseen Common Language Runtime (CLR) -ympäristössä.
C# 2.0 julkaistiin vuonna 2005 .NET Framework 2.0 -version yhteydessä. Versiossa esiteltiin geneeriset tyypit ja menetelmät, nullable-arvotyypit, anonyymit metodit, iteraattorit (yield return), osittaiset tyypit sekä staattiset luokat. Geneerisyys toteutettiin CLR-tasolla ilman tyyppien poistoa (type erasure), mikä paransi suorituskykyä ja tyyppiturvallisuutta.
C# 3.0 julkaistiin vuonna 2007 .NET Framework 3.5 -alustan mukana. Versio keskittyi kielen ilmaisukyvyn parantamiseen ja LINQ-kyselyjen tukemiseen. Uusia ominaisuuksia olivat lambda-lausekkeet, paikallisen tyypin päättely (var), anonyymit tyypit, laajennusmetodit, kyselylausekerakenne sekä ilmaisupuut (expression trees).
C# 4.0 julkaistiin vuonna 2010 .NET Framework 4 -alustan yhteydessä. Versio toi dynaamisen sidonnan (dynamic), nimetyt ja valinnaiset parametrit sekä parannetun kovarianssin ja kontravarianssin geneerisille rajapinnoille ja delegaateille. Ominaisuudet helpottivat yhteentoimivuutta dynaamisten kielten ja COM-komponenttien kanssa.
.NET Core ja avoimen lähdekoodin vaihe Vuosina 2012–2015 julkaistut C# 5.0 ja C# 6.0 keskittyivät kielen ilmaisukyvyn ja käytettävyyden parantamiseen. C# 5.0 (2012) toi asynkronisen ohjelmoinnin async/await-rakenteet. C# 6.0 (2015) esitteli useita käytännön parannuksia, kuten merkkijonointerpolaation, staattiset using-lausekkeet, lausekemuotoiset jäsenet, null-ehtoisen operaattorin parannukset sekä suodatellun poikkeuskäsittelyn.
Vuonna 2014 Microsoft avasi C#:n kääntäjäalustan Roslyn lähdekoodin ja siirsi kehityksen GitHubiin .NET Foundation -säätiön alaisuuteen. Samalla käynnistettiin avoimen lähdekoodin .NET Core -alusta, jonka ensimmäinen versio julkaistiin vuonna 2016. Se mahdollisti C#-sovellusten ajamisen Windowsin ohella myös Linux- ja macOS-käyttöjärjestelmissä. Avoimuus laajensi merkittävästi kehittäjäyhteisön osallistumista kielen ja alustan kehitykseen.
C# 7.0 -sarja (2017–2019) sidottiin tiiviisti .NET Core -julkaisusykliin. Versiot toivat muun muassa arvotuuplit, parannetun mallinsovituksen, paikalliset funktiot, ref-palautukset ja suorituskykyä parantavia rakenteita kuten Span<T> sekä ref struct. C# 8.0 (2019) esitteli nullable-viitetyypit, oletustoteutukset rajapinnoille, asynkroniset virrat sekä indices and ranges -syntaksit. Nämä ominaisuudet vahvistivat kielen asemaa turvallisessa ja monialustaisessa sovelluskehityksessä.
Yhtenäinen .NET-alusta (5+) ja uusimmat kehitysaskeleet Vuodesta 2020 alkaen Microsoft yhdisti aiemmat .NET Framework-, .NET Core- ja Xamarin/Mono-haarat yhtenäiseen .NET-alustaan. .NET 5 julkaistiin vuonna 2020, ja sitä seurasivat .NET 6 (2021), .NET 7 (2022), .NET 8 (2023), .NET 9 (2024) ja .NET 10 (2025). Julkaisut noudattavat vuosittaista rytmiä, jossa parilliset .NET-versiot ovat pitkäaikaisen tuen (Long-Term Support, LTS) julkaisuja ja parittomat lyhyemmän tuen (Standard Term Support, STS) julkaisuja.
C# 9.0 julkaistiin .NET 5:n yhteydessä vuonna 2020. Versio toi record-tyypit, init only -ominaisuudet, ylätason ohjelmat sekä parannuksia mallinsovitukseen. C# 10.0 (2021) esitteli globaalit using-lauselmat, tiedostokohtaiset nimiavaruudet, record struct -tyypit sekä parannuksia lambda-lausekkeisiin.
C# 11.0 (2022) toi raa'at merkkijonoliteraalit, listamallit, geneeriset attribuutit ja required-jäsenet. C# 12.0 (2023) laajensi pääkonstruktorit luokkiin ja rakenteisiin, lisäsi kokoelmailmaisut sekä paransi lambda-parametrien oletusarvoja ja geneeristä ohjelmointia.
C# 13.0 (2024) ja C# 14.0 (2025) julkaistiin .NET 9- ja .NET 10 -alustojen mukana. Versiot toivat parannuksia muun muassa params-kokoelmiin, lock-objektiin, ref struct -rajapintoihin sekä tyyppien laajentamiseen ilman perintää (extension members). Kielen kehitys jatkuu vuosittaisena ja avoimena prosessina .NET-alustan rinnalla.
Suunnittelutavoitteet ja vaikutteet Suunnittelutavoitteet C# suunniteltiin yleiskäyttöiseksi, moderniksi ohjelmointikieleksi, joka tukee useita ohjelmointiparadigmoja mutta säilyttää C-suvun kielille tyypillisen syntaksin. Kielen keskeisiin tavoitteisiin kuuluivat vahva staattinen tyyppijärjestelmä, automaattinen roskienkeruu sekä tuki turvalliselle ja ylläpidettävälle sovelluskehitykselle. C# suunniteltiin tarjoamaan C++-kielen suorituskykyä muistuttava teho yhdistettynä korkean tason kielen kaltaiseen kehitysmukavuuteen.
C# on tiiviisti sidottu Common Language Infrastructure (CLI) ja Common Language Runtime (CLR) -ympäristöihin. Kielen suunnittelutavoitteisiin kuuluu, että C#:llä kirjoitetut ohjelmat käännetään ECMA-334-määrittelyn mukaan yhteiseen välitasokoodiin Common Intermediate Language (CIL), jota voivat jakaa useat eri CLI-yhteensopivat kielet. Tavoitteena on tukea kielien välistä yhteentoimivuutta eri CLI-yhteensopivien kielten, kuten Visual Basic .NETin ja muiden .NET-kielten, välillä, sekä vahvaa tyyppiturvallisuutta, versioitavuutta ja komponenttipohjaista sovelluskehitystä.
Kielen suunnittelussa otettiin huomioon sekä järjestelmäohjelmoinnin että sovelluskehityksen tarpeet. C# tarjoaa korkean tason ominaisuuksia, kuten poikkeuskäsittelyn, automaattisen muistinhallinnan ja laajan luokkakirjaston, mutta mahdollistaa myös matalamman tason ohjelmoinnin esimerkiksi osoittimia hyödyntävän unsafe-tilan kautta silloin, kun halutaan minimoida roskienkeruun aiheuttamia viiveitä tai integroitua olemassa oleviin rajapintoihin.
Vaikutteet muista kielistä C# kuuluu syntaksiltaan C-sukuisiin kieliin, ja sen perusrakenne – lohkot, ohjausrakenteet, tyyppimääritykset ja operaattorit – muistuttavat läheisesti C++- ja Java-kieliä. Tämä helpottaa siirtymistä aiemmista C-tyyppisistä kielistä C#:ään, ja mahdollistaa olemassa olevien ohjelmointitapojen hyödyntämisen .NET-ympäristössä. C#:n olio-malli, rajapinnat ja poikkeuskäsittely noudattavat pitkälti samoja periaatteita kuin muissa modernissa olio-ohjelmointikielissä.
Kielen suunnitteluun vaikuttivat myös komponenttipohjaiset kielet ja ympäristöt, kuten Visual Basic ja Delphi, joissa korostuvat ominaisuudet, tapahtumat ja versioitavat kirjastot. C#:ssä nämä ideat yhdistyvät CLR:n metatietomalliin ja kokoonpanoihin (assemblies), mikä tukee komponenttipohjaista ohjelmistokehitystä, uudelleenkäytettävyyttä ja versiohallittuja kirjastoja.
Lisäksi C#:n kehityksessä on omaksuttu ideoita mm. funktionaalisesta ohjelmoinnista, mikä näkyy esimerkiksi lambda-lausekkeiden, LINQ-kyselyjen ja mallinsovituksen kaltaisina ominaisuuksina. Kielen myöhemmät versiot ovat tuoneet lisää funktionaalisia piirteitä, kuten immuuttisuutta korostavia record-tyyppejä ja ilmaisupuita, säilyttäen samalla taaksepäin yhteensopivuuden alkuperäisen C-tyylisen syntaksin kanssa.
Tyyppijärjestelmä ja muistinhallinta Tyyppijärjestelmä C#:ssä on staattinen ja vahva tyyppijärjestelmä, joka perustuu CLI:n yhteiseen tyyppijärjestelmään (Common Type System, CTS). Kaikki tyypit – sekä kielen sisäänrakennetut että käyttäjän määrittelemät – jakautuvat kahteen pääryhmään: arvotyyppeihin (esimerkiksi peruslukutyypit, rakenteet ja enumeraatiot) ja viitetyyppeihin (esimerkiksi luokat, rajapinnat, taulukot ja delegaatit. Tyyppijärjestelmä on nimellinen ja suunniteltu siten, että kääntäjä ja CLR voivat tarkistaa tyypinmukaisuuden ja estää suuren osan ajoaikaisista tyyppivirheistä jo käännösvaiheessa.
Arvotyypit tallennetaan tyypillisesti suoraan muuttujan muistipaikkaan (esimerkiksi pinossa tai osana toista rakennetta), kun taas viitetyypeistä talletetaan viite kekoon varattuun olioon. Kaikki tyypit voidaan käsitellä object-perustyypin kautta, mikä mahdollistaa yhtenäisen käsittelyn ja esimerkiksi kokoelmiin tallentamisen. Arvotyypin pakkaaminen (boxing) muuntaa sen viitetyypiksi ja purkaminen (unboxing) takaisin arvotyypiksi; tämä on osa CTS-määrittelyä ja vaikuttaa sekä suorituskykyyn että muistinkäyttöön.
Kieli tukee laajaa joukkoa generisia kokoelmia ja geneeristä ohjelmointia, jossa tyyppiparametrit välitetään suoraan CLR-tason generisyytenä ilman tyyppien poistoa (type erasure). Tämä parantaa suorituskykyä ja vähentää pakkausoperaatioiden tarvetta verrattuna ei-geneerisiin rakenteisiin. Lisäksi C#:n tyyppipäättely (esimerkiksi var-avainsanan ja lambda-lausekkeiden yhteydessä) helpottaa koodin kirjoittamista muuttamatta tyyppijärjestelmän staattista luonnetta.
C#:n null-käsittely perustuu sekä arvotyyppien nullable-laajennoksiin (T? enumeraatioille ja muille arvotyypeille) että nullable-viitetyyppeihin, jotka otettiin käyttöön C# 8.0 -versiossa. Null-viitetyypit yhdistävät käännösaikaisen analyysin ja annotaatiot (esimerkiksi string? ja string) vähentääkseen null-viitevirheiden todennäköisyyttä tuotantokoodissa.
Muistinhallinta C#:ssa muistinhallinta on pääosin automaattista ja perustuu roskienkeruuseen CLR-ympäristössä. CLR hallinnoi viitetyyppien elinkaarta sijoittamalla ne hallittuun kekoon ja keräämällä käyttämättömät oliot pois generaatioperusteisen roskienkeruun avulla. Tämä vähentää muistivuotojen riskiä ja helpottaa sovelluskehitystä verrattuna manuaaliseen muistinhallintaan, mutta tekee olioiden tuhoamisesta ei-determinististä: ohjelmoija ei voi tarkasti kontrolloida, milloin yksittäinen olio vapautetaan.