Naar inhoud springen

C Sharp

Uit Wikipedia, de vrije encyclopedie
De titel van deze pagina kan door technische beperkingen niet correct worden weergegeven als C#. Dit artikel artikel gaat over de programmeertaal, voor de muzieknoot die ook wordt weergegeven als C# zie Cis.
C#
C Sharp
Paradigma gestructureerd programmeren, imperatief programmeren, objectgeoriënteerd programmeren, Event, functioneel programmeren, Genericiteit, Reflectie
Verschenen 2001
Ontwikkeld door Microsoft
Huidige versie 13[1] Bewerken op Wikidata
Typesysteem nominatief typesysteem, type-inferentie, dynamisch typesysteem
Implementaties .NET Framework, Mono
Beïnvloed door C++, C, Java, Delphi, Modula-3, Cω, Eiffel, F#, Haskell, Icon, J#, Object Pascal, Rust, ML, Visual Basic
Invloed op D, Java, Vala, Windows PowerShell
Bestandsextensies cs, csx
Website (en) C# op de website van Microsoft
Portaal  Portaalicoon   Informatica
Voorbeeld van 'n HalloWêreld (Zuid-Afrikaans)

C# (Engels uitgesproken als "C sharp" ) is een programmeertaal ontwikkeld door Microsoft als deel van het .NET-initiatief, en later geaccepteerd als standaard door ECMA (ECMA-334) en ISO (ISO/IEC 23270). C# is objectgeoriënteerd en lijkt qua syntaxis en semantiek sterk op Java, maar bevat vooral in latere versies allerlei voorzieningen waardoor ook in andere programmeerstijlen gewerkt kan worden, terwijl vooral in de bibliotheken en programmeeromgeving een sterke invloed van Object Pascal en Delphi te zien is. Anders Hejlsberg, de ontwerper van Delphi, heeft een leidende rol gehad in het ontwerpen van C# en .NET.

De taal is geïnspireerd door C. De naam is een verwijzing naar de muziek: een toon die een halve toon hoger is dan een C heet C# (Engelse uitspraak: C sharp). In het Nederlands zou dat Cis zijn.

C# is ontworpen door Anders Hejlsberg en het ontwikkelingsteam wordt momenteel[(sinds) wanneer?] geleid door Mads Torgersen.

Ontwerpdoelen

[bewerken | brontekst bewerken]

De Ecma-norm somt deze ontwerpdoelen op voor C#:[2]

  • De taal is bedoeld als een eenvoudige, moderne, objectgeoriënteerde programmeertaal voor algemene doeleinden.
  • De taal en implementaties daarvan zouden ondersteuning moeten bieden voor software-engineeringprincipes zoals sterke typecontrole, controle van arraygrenzen, detectie van pogingen om niet-geïnitialiseerde variabelen te gebruiken en automatische garbage collection. Robuustheid van software, duurzaamheid en productiviteit van programmeurs zijn belangrijk.
  • De taal is bedoeld voor gebruik bij het ontwikkelen van softwarecomponenten die geschikt zijn voor implementatie in gedistribueerde omgevingen.
  • Draagbaarheid is erg belangrijk voor broncode en programmeurs, vooral degenen die al bekend zijn met C en C++.
  • Ondersteuning bij internationalisering is erg belangrijk.
  • C# is bedoeld om geschikt te zijn voor het schrijven van applicaties voor zowel gehoste als geïntegreerde systemen, variërend van zeer grote die geavanceerde besturingssystemen gebruiken, tot zeer kleine met speciale functies.
  • Hoewel C#-toepassingen bedoeld zijn om zuinig te zijn met betrekking tot geheugen- en verwerkingsvermogenvereisten, was de taal niet bedoeld om rechtstreeks te concurreren op prestaties en grootte met C of assembleertaal.

Tijdens de ontwikkeling van het .NET-framework werden de klassenbibliotheken oorspronkelijk geschreven met behulp van een beheerdecode-compilersysteem genaamd "Simple Managed C" (SMC).[3][4] In januari 1999 vormde Anders Hejlsberg een team om een nieuwe taal te bouwen genaamd Cool, wat stond voor "C-like Object Oriented Language".[5] Microsoft had overwogen de naam "Cool" te behouden als de definitieve naam van de taal, maar koos ervoor dit niet te doen vanwege handelsmerkredenen. Tegen de tijd dat het .NET-project publiekelijk werd aangekondigd op de Professionele Developers Conference van juli 2000, was de taal omgedoopt tot C#, waarbij de klassenbibliotheken en de ASP.NET-runtime waren geporteerd naar C#.

Hejlsberg is de belangrijkste ontwerper en hoofdarchitect van C# bij Microsoft, en was eerder betrokken bij het ontwerp van Turbo Pascal, Embarcadero Delphi (voorheen CodeGear Delphi, Inprise Delphi en Borland Delphi) en Visual J++. In interviews en technische artikelen heeft hij verklaard dat gebreken[6] in de meeste belangrijke programmeertalen (bijv. C++, Java, Delphi en Smalltalk) de basis waren voor de Common Language Runtime (CLR), die op zijn beurt het ontwerp van de C#-taal zelf vormde.

James Gosling, die de programmeertaal Java in 1994 creëerde, en Bill Joy, medeoprichter van Sun Microsystems, de grondlegger van Java, noemde C# een "imitatie" van Java; Gosling zei verder dat "[C#] een soort Java is waarvan de betrouwbaarheid, productiviteit en beveiliging zijn verwijderd."[7][8] Klaus Kreft en Angelika Langer (auteurs van een C++ streams-boek) verklaarden in een blogpost dat "Java en C# bijna identieke programmeertalen zijn. Saaie herhaling zonder innovatie".[9] "Bijna niemand zal beweren dat Java of C# revolutionaire programmeertalen zijn die de manier waarop we programma's schrijven hebben veranderd" en "C# leende veel van Java - en vice versa. Nu C# boxing en unboxing ondersteunt, hebben we zeer veel vergelijkbare functies als in Java."[9] In juli 2000 zei Hejlsberg dat C# "geen Java-kloon is en veel dichter bij C++ ligt in zijn ontwerp. C# leent de meeste van zijn operators, keywords en statements direct van C++, we hebben gekeken naar Java, naar Modula 2, C en we keken naar Smalltalk. We hebben ook een aantal taaleigenschappen die Java niet overgenomen heeft, waarom zijn er bijvoorbeeld geen enums in Java? We hebben ook operator overloading en typeconversies, ook ligt onze complete structuur voor namespaces veel dichter tegen C++ aan".[10]

Sinds de release van C# 2.0 in november 2005 zijn de C#- en Java-talen geëvolueerd op steeds meer uiteenlopende trajecten, en zijn ze twee behoorlijk verschillende talen geworden. Een van de eerste grote verschuivingen kwam met de toevoeging van genericiteit aan beide talen, met enorm verschillende implementaties. C# maakt gebruik van reïficatie om "eersteklas" generieke objecten te leveren die kunnen worden gebruikt zoals elke andere klasse, waarbij codegeneratie wordt uitgevoerd tijdens het laden van de klasse.[11] Bovendien heeft C# verschillende belangrijke functies toegevoegd om het programmeren in functionele stijl mogelijk te maken, met als hoogtepunt de LINQ-extensies die zijn uitgebracht met C # 3.0 en het ondersteunende raamwerk van lambda-expressies, uitbreidingsmethoden, en anonieme typen.[12] Deze functies stellen C -programmeurs in staat functionele programmeertechnieken te gebruiken, zoals sluitingen, wanneer dit voordelig is voor hun toepassing. De LINQ-extensies en de functionele import helpen ontwikkelaars de hoeveelheid standaardcode te verminderen die is opgenomen in veelvoorkomende taken zoals het opvragen van een database, het ontleden van een XML-bestand of het doorzoeken van een datastructuur, waarbij de nadruk wordt verschoven naar de eigenlijke programmalogica om de leesbaarheid te verbeteren en onderhoudbaarheid.

C# had vroeger een mascotte genaamd Andy (genoemd naar Anders Hejlsberg). Die is op 29 januari 2004 gestopt.

C# was oorspronkelijk ter beoordeling voorgelegd aan de ISO-subcommissie JTC 1/SC 22, onder ISO / IEC 23270: 2003, werd ingetrokken en werd vervolgens goedgekeurd onder ISO / IEC 23270: 2006.

Microsoft gebruikte de naam C# voor het eerst in 1988 voor een variant van de C-taal die is ontworpen voor incrementele compilatie.[13] Dat project is niet voltooid, maar de naam leefde voort.

De naam is geïnspireerd door de muziek. De toon cis heet in het Engels "C♯", uitgesproken als "c sharp".[14] Dit is vergelijkbaar met de naam van de programmeertaal C++, waar "++" aangeeft dat een variabele na evaluatie met 1 moet worden verhoogd. Het kruissymbool lijkt ook op een ligatuur van vier "+" symbolen (in een raster van twee bij twee), wat verder impliceert dat de taal een toename is van C++.

Vanwege technische beperkingen van weergave (standaard fonts, browsers etc.) en het feit dat het kruis niet aanwezig op de meeste toetsenborden (U+266F ♯ MUSIC SHARP SIGN (HTML ♯ of ♯)), werd het nummerteken of hekje (U+0023 # NUMBER SIGN (HTML # of #)) gekozen om het kruis in de geschreven naam van de programmeertaal te benaderen. Deze conventie wordt weerspiegeld in de ECMA-334-C#-taalspecificatie.

Het achtervoegsel "sharp" is gebruikt door een aantal andere .NET-talen die varianten zijn van bestaande talen, waaronder J# (een .NET-taal die ook is ontworpen door Microsoft en is afgeleid van Java 1.1), A♯ (van Ada) en de functionele programmeertaal taal F#. De oorspronkelijke implementatie van Eiffel voor .NET heette Eiffel♯, een naam die weer opgedoekt is omdat de volledige taal van Eiffel nu wordt ondersteund. Het achtervoegsel is ook gebruikt voor bibliotheken, zoals Gtk# (een .NET- wrapper voor GTK+ en andere GNOME-bibliotheken) en Cocoa# (een wrapper voor Cocoa).

Versie Taalspecificatie Datum .Net Versie Visual Studio
Ecma ISO/IEC Microsoft
C# 1.0 december 2002[15] april 2003 januari 2002 januari 2002 .Net Framework 1.0 Visual Studio .Net 2002
  • C# 1.1
  • C# 1.2
oktober 2003 april 2003 .Net Framework 1.1 Visual Studio .Net 2003
C# 2.0 Juni 2006[16] september 2005 november 2005
  • .Net Framework 2.0
  • .Net Framework 3.0
  • Visual Studio 2005
  • Visual Studio 2008
C# 3.0 augustus 2007 november 2007
  • .Net Framework 2.0 (behalve LINQ)
  • .Net Framework 3.0 (behalve LINQ)
  • .Net Framework 3.5
Visual Studio 2008
C# 4.0 april 2010 april 2010 .Net Framework 4 Visual Studio 2010
C# 5.0 juni 2013 augustus 2012 .Net Framework 4.5
  • Visual Studio 2012
  • Visual Studio 2013
C# 6.0[17] draft juli 2015
  • .Net Framework 4.6
  • .Net Core 1.0
  • .Net Core 1.1
Visual Studio 2015
C# 7.0[18] specificatievoorstel maart 2017 .Net Framework 4.7 Visual Studio 2017 versie 15.0
C# 7.1[18] specificatievoorstel augustus 2017 .Net Core 2.0 Visual Studio 2017 versie 15.3
C# 7.2[18] specificatievoorstel november 2017 Visual Studio 2017 versie 15.5
C# 7.3[18] specificatievoorstel mei 2018
  • .Net Core 2.1
  • .Net Core 2.2
  • .Net Framework 4.8
Visual Studio 2017 verse 15.7
C# 8.0[19] specificatievoorstel september 2019 .Net Core 3.0 Visual Studio 2019 versie 16.3
C# 9.0[20] specificatievoorstel november 2020 .Net 5.0 Visual Studio 2019 versie 16.8[21]
C# 10.0[22] specificatievoorstel november 2021 .Net 6.0 Visual Studio 2022 versie 17.0[23]
C# 11.0[24] specificatievoorstel november 2022 .Net 7.0 Visual Studio 2022 versie 17.4[25]
C# 12.0[26] specificatievoorstel december 2023 .Net 8.0 Visual Studio 2022 versie 17.6[27]

Nieuwe taalkenmerken

[bewerken | brontekst bewerken]

In de volgende versietabel zijn de Engelse termen erbij geplaatst omdat deze meer gangbaar zijn binnen het domein.

  • Impliciet getypeerde lokale variabelen
  • Object- en collectie-initializers
  • Auto-implemented eigenschappen
  • Anonieme types
  • Extensiemethoden
  • Query-expressies
  • Anonieme functies / lambda-expressies
  • Expressiebomen
  • Partiële methoden
  • Dynamische bindingen
  • Benoemde en optionele argumenten
  • Generieke co- en contravariantie
  • Embedded interop-typen ("NoPIA")
  • Async/await / asynchrone methoden
  • Aanroeper-informatie-attributen
  • Compiler-als-een-service
  • Import van statische type leden in namespace
  • Exceptiefilters
  • Await in catch/finally-blokken
  • Auto-property-initializers
  • Default values for getter-only-properties
  • Expressie-bodied leden (roslyn)
  • Null propagator / Veilige navigatie-operator / null-condities-operator
  • String-interpolatie
  • nameof-operator
  • Dictionary initializer
  • Inline-out-variabeledeclaraties
  • Patroonmatching
  • Tuple-types en tuple-literals
  • Deconstructie
  • Lokale functies
  • Digitale scheiders
  • Binaire literals
  • Ref-returns en locals
  • Generieke async-return-typen
  • Expressie-bodied constructors en finalizers
  • Expressie-bodied getters en setters
  • Throw kan ook worden gebruikt als expressie
  • Async main
  • Standaard literal-expressies
  • Afgeleide tuple-elementnamen
  • Referentiesemantiek met value-typen
  • Niet-trailing named arguments
  • Leidende underscores in numerieke literals
  • private protected-toegang-modifier
  • Toegang verkrijgen tot vaste velden zonder pinning
  • Opnieuw toekennen van ref local-variabelen
  • Gebruik maken van initializers op stackalloc-arrays
  • Gebruik maken van fixed statements met elk type dat een patroon ondersteund
  • Gebruik maken van additionele algemene constraints
  • readonly-struct-leden
  • Standaard interfaceleden
  • switch-expressies
  • Property, Tuple, en positionele patronen
  • using-declaraties
  • Statische local-functies
  • Disposable ref struct
  • Nullable referentietypen
  • Indices en bereiken
  • Null-coalescing toekenningen
  • Async Streams
  • Doel getypeerde "new"
  • Overslaan van lokale initialisatie
  • Native sized ints
  • Attributen op lokale functies
  • Functiepointers
  • Verbeteringen voor patroonmatching
  • Statische lambda's
  • Records
  • Target-getypeerde conditionelen
  • Covariante returns
  • Extensie getenumerator
  • Module-initializers
  • Uitbreiding partial
  • Top-level-statements

Hieronder staat een voorbeeld van een kleine Hello world-applicatie, geschreven in C#:

using System;

public class Hello
{
  private static void Main()
  {
    Console.WriteLine("Hello World");
  }
}

Een bronbestand van C# wordt opgeslagen met cs-bestandsextensie, bijvoorbeeld 'Hello.cs'.

Vergelijking met Java en C++

[bewerken | brontekst bewerken]
  • Overerving: zoals in Java is er een onderscheid tussen interfaces, die alleen methodedeclaraties bevatten, en klassen, die methoden kunnen implementeren, en kan een klasse maar van één andere klasse overerven, maar meerdere interfaces implementeren. In C++ wordt dit onderscheid niet gemaakt en is multiple inheritance van klassen mogelijk.
  • bool: er is geen impliciete conversie tussen bool en int zoals bij C++. Conversies kunnen – net als bij C++ en Java – worden uitgevoerd met behulp van typecasting. Een Boolean is een value type. Daarnaast kunnen bij C# "primitieve" types als int en bool worden aangesproken als een object (boxing), waardoor een conversie als 5.ToString() mogelijk is; Java heeft dit tegenwoordig ook.
  • struct: C# (en het .NET-framework) maakt een onderscheid tussen reference types en value types. Een value type wordt in C# gedeclareerd als struct, een reference type als class. Verder hebben ze dezelfde gebruiksmogelijkheden; een struct kan bijvoorbeeld eigenschappen en methoden hebben. Het verschil is dat de instantievariabelen van een value type niet gewijzigd kunnen worden (zulke wijzigingen hebben geen effect). Met structs kan worden voorkomen dat zeer veel kleine objecten de overhead van garbage collection met zich meedragen. In C++ zijn de velden van een struct wel degelijk te wijzigen. Java kent geen structs.
  • delegate: Dit zijn type-safe functiepointers. Ze zijn vergelijkbaar met functiepointers in C++ en functionele interfaces in Java.
  • base en override: base is zoals bij Java super en override is zoals bij Java en C++ virtual.
  • Preprocessor directives: Java kent deze helemaal niet, C# alleen #define, waarmee een constante waarde kan worden gedefinieerd, en #if, dat op die waarde test, zodat conditionele compilatie mogelijk is. Niet ondersteund worden expressies in #define, #include, en andere features van de C/C++-preprocessor. De rol van #include in C++ wordt vervuld door using in C# (en import in Java), die verwijzen naar namespaces in plaats van naar broncode.
  • operators: hier bestaan extra operators ten opzichte van C++, zoals de is, as, ?? en typeof, een subset hiervan bestaat ook in Java. C# ondersteunt net als C++ operator-overloading; Java niet.
  • Main: wordt gebruikt om het entry point voor een programma aan te geven, zoals in Java.
  • argument passing: is in principe zoals in Java: normaal gesproken is het call by value, maar ref en out kunnen worden gebruikt om parameters by reference door te geven, wat betekent dat een toewijzing aan de argumentvariabele in de aangeroepen code ook de meegegeven variabele wijzigt in de aanroepende code; unsafe wordt gebruikt om in unmanaged code expliciete pointers (dat wil zeggen geheugenadressen) door te geven.
  • strings: in tegenstelling tot C waar er geen speciale klasse is voor strings, maar een string gewoon een pointer naar een stuk geheugen is waar de string staat, gebruiken C# en Java beide een overkoepelende String-klasse. Deze zijn meestal 'copy-on-write' en zijn makkelijker aan te passen dan de C-strings. C++ ondersteunt beide methoden.
  • foreach, in: laat toe om door Xray arrays en collecties te itereren (waardoor de bij een for-lus benodigde expliciete indexvariabele overbodig wordt) maar ook door willekeurige enumerables, die niet altijd, zoals arrays en collecties, een vooraf vastgelegde reeks elementen hoeven te bevatten; ze komen min of meer overeen met de lazy lists uit het functioneel programmeren. Java gebruikt zulke iteratie ook, en heeft sinds versie 1.5 ook de foreach-constructie.
  • using: wordt gebruikt om naar andere namespaces te verwijzen zonder dat men telkens de volledige naam moet opgeven. Ook in Java is deze functionaliteit in de vorm van 'packages' aanwezig en kunnen packages geïmporteerd worden met het import-statement. In C bestaat dit niet in de taal, maar wordt het gesimuleerd met de preprocessor, in C++ bestaat dit echter wel in de vorm van 'using namespace'.
  • Destructor: net zoals bij Java is er automatic garbage collection, die ervoor zorgt dat de programmeur geen rekening hoeft te houden met het opruimen van het geheugen. In C++ en C moet de programmeur dit wel zelf doen, al bestaan er bibliotheken die er bij kunnen helpen. Het is wel mogelijk in C# om zogenaamde 'unsafe' (unmanaged) code te schrijven met pointers, net als in C++ en C.
  • Machinecode versus Byte code: C# en Java worden beide naar byte-code gecompileerd voor een virtuele machine (VM), die ook wel de runtime wordt genoemd, en die eenmalig moet worden opgestart; deze machine zal met JIT (Just-in-time-compilatie) de bytecode eenmalig naar machinecode compileren en laten uitvoeren, en is ook verantwoordelijk voor garbage collection. Programmatuur in een taal als C++ daarentegen wordt direct naar machinetaal gecompileerd, waarna de gecompileerde programmatuur wordt geïnstalleerd op de machines waar de programmatuur op moet draaien; die programmatuur wordt dan direct door de processor uitgevoerd. Het gebruik van de virtuele machine heeft als nadeel de overhead van het opstarten en het (eenmalig) compileren; anderzijds maakt het bepaalde optimalisaties in het compileren mogelijk die bij compilatie vooraf onmogelijk zijn.

Common Intermediate Language

[bewerken | brontekst bewerken]

De Common Intermediate Language (CIL) is de specificatie van de bytecode waar alle .NET-talen naartoe compileren. De CIL-code wordt door de Common Language Runtime (CLR) at-runtime omgezet naar machinecode en uitgevoerd. Omdat de CIL-code at-runtime wordt gecompileerd vlak voor deze wordt aangeroepen, spreekt men wel van JIT (Just In Time)-compilatie. CIL is te vergelijken met de bytecode in Java's .class-bestanden. Ook Java's VM werkt op eenzelfde manier als de CLR van .NET.

CIL heette voorheen MSIL, wat de afkorting was voor Microsoft Intermediate Language, maar is van naam veranderd om in aanmerking te komen als ISO-standaard.

Gebruik als scripttaal

[bewerken | brontekst bewerken]

Door zijn flexibiliteit kan C# ook als scripttaal worden gebruikt. Zo is dit standaard geïmplementeerd in Unity3D[31] en is het ook mogelijk om C# als scripttaal te gebruiken voor de Unreal engine.[32] Ook kan C# als scripttaal worden gebruikt met behulp van cs-script[33] en is het mogelijk C# als scripttaal te gebruiken in applicaties die met C++ zijn geschreven.[34]

Door gebruik te maken van ASP.NET kan C# gebruikt worden als alternatief voor PHP.

[bewerken | brontekst bewerken]