Wat is de beste programmeertaal voor .NET?
Door Michiel van Otegem
20 augustus 2006
Voor het maken van applicaties op het .NET Framework is er een ruime keuze uit
programmeertalen. De vraag welke de beste is dient zich dus aan op het moment dat je
een keuze moet maken.
Op dit moment zijn er zo'n 20 talen waarmee je applicaties kunt maken voor het .NET
Framework. Voordat we überhaupt kunnen bepalen welke taal het beste is, moeten we eerst
weten wat de verschillen (en overeenkomsten) zijn tussen de talen. Daarbij is het ook
van belang waarom er zoveel talen zijn, en waardoor dat mogelijk is.
Waarom zoveel talen?
Microsoft levert het .NET Framework standaard met ondersteuning voor 4 talen: C#, J#
(vanaf versie 1.1), JScript.NET, en Visual Basic .NET (VB.NET). Dat Microsoft juist
deze talen gekozen heeft is geen toeval. VB.NET is duidelijk gericht op de bestaande
ontwikkelaars die werken met Visual Basic 6, Visual Basic Scription Edition (VBScript),
of Visual Basic for Applications (VBA), ruim 5 miljoen in getal. JScript.NET is een
afgeleide van JavaScript (of eigenlijk ECMAScript), hetgeen een populaire taal is bij
het maken van internet applicaties. J# biedt Java-ontwikkelaars, en dan met name die
met Visual J++ werken, een makkelijke opstap naar het .NET Framework. C# tenslotte is
een volledig nieuwe taal die gebaseerd is op C en C++, en die concepten leent uit de
Java wereld. Doordat C# nieuw is, is het een hele "schone" taal, en maakt deze bovendien
optimaal gebruik van de mogelijkheden die het .NET Framework biedt. Verder is C# door
ontwikkelaars makkelijker op te pikken dan C en C++, en is een overstap van Java ook
niet moeilijk. Al met al is de keuze van Microsoft voor de ondersteunde talen er dus
op gericht om zoveel mogelijk ontwikkelaars te bereiken.
De vraag die zich nu aandient is waarom er dan nog zoveel andere talen zijn. Die vraag
is niet eenduidig te beantwoorden, maar de talen die ondersteund worden geven wel een
belangrijke reden: migratie. Naast Visual C++ waarvoor Microsoft zelf ondersteuning
gemaakt heeft, hebben allerlei andere partijen zoals Cobol, Fortran, Pascal, en
Perl aangepast voor het .NET Framework (zie http://www.dotnetpowered.com/languages.aspx). Dit zijn vrijwel allemaal talen die al lang mee gaan,
en vooral Cobol en Fortran worden nog veel gebruikt in mainframes. Er komt echter een
tijd dat die mainframes vervangen moeten worden, en dan zou het vervelend zijn als
die miljoenen regels code die men daarvoor geschreven heeft het raam uit kan gooien
en volledig opnieuw moet schrijven in een andere taal. Een veel betere oplossing is
deze code aan te passen op een nieuw platform en door deze talen te ondersteunen biedt
het .NET Framework een goed alternatief.
Hoe zijn zoveel talen mogelijk?
Dat zoveel talen mogelijk zijn is al een opmerkelijk feit op zich. Het wordt nog
opmerkelijker als je in acht neemt dat de talen naadloos met elkaar samen kunnen
werken en je in een applicatie meerdere talen kunt gebruiken. Dat dit kan komt
doordat al de talen moeten voldoen aan dezelfde regels, de zogenaamde Common Language
Specification (CLS). Onderdeel van de CLS is de Common Type Specification (CTS) die
ervoor zorgt dat alle talen dezelfde basistypen gebruiken. Dit houdt onder andere in
dat een integer altijd 32-bits lang is, dat er gedefinieerd is wat een string is, en
dat er ook vast ligt hoe een object eruit ziet. Als dit niet zo zou zijn, dan zouden
de talen niet met elkaar kunnen communiceren. Als bijvoorbeeld de ene taal een 16-bits
integer zou gebruiken en een andere een 32-bits integer, dan ontstaan er problemen als
de 32-bits taal een getal naar de andere taal zou sturen dat niet past in 16-bits. Dat
is hetzelfde als proberen een vierkant blokje door een rond gaatje te krijgen, en dat
is dus vragen om problemen.
Een ander belangrijk aspect is dat de talen niet naar machinetaal gecompileerd worden,
maar naar een tussentaal, de zogenaamde Microsoft Intermediate Language (MSIL). Als
een applicatie wordt uitgevoerd, wordt die MSIL weer gecompileerd naar machinetaal.
Die compilatie gebeurt niet in één keer maar in delen, omdat anders de gebruiker erg
lang zou moeten wachten tot de applicatie gestart is. Door alleen de op dat moment
benodigde delen te compileren, wordt de compilatie over een lange tijd uitgesmeerd,
zodat de gebruiker er niets van merkt. Ook worden de eenmaal gecompileerde delen in
het geheugen opgeslagen, zodat ze niet nogmaals gecompileerd hoeven te worden. Het in
delen compileren wordt gedaan door een Just-In-Time (JIT) compiler, die onderdeel
uitmaakt van de Common Language Runtime (CLR), die verantwoordelijk is voor het
uitvoeren van een applicatie. De CLR controleert ook alle code om te zorgen dat er
geen ongeoorloofde operaties worden uitgevoerd, en om te zorgen dat er geen
geheugenlekken of andere problemen kunnen ontstaan. Dit betekent dat ontwikkelaars
minder fouten kunnen maken, maar ook dat het systeem veel minder vatbaar is voor
kwaadaardige code. Hoe de verschillende talen door de CLR uitgevoerd worden zie je in
Afbeelding 1.

Afbeelding 1, Talen worden uitgevoerd door de CLR
Naast de al genoemde voordelen die MSIL en de CLR bieden, zijn er nog een aantal andere
belangrijke voordelen. Ten eerste kan de uiteindelijke machinetaal geoptimaliseerd worden
voor de processor en de hoeveelheid geheugen die beschikbaar is. Hierdoor is er ondanks
de JIT-compilatie niet of nauwelijks verschil in snelheid met applicaties die direct
naar machinetaal gecompileerd zijn, en is het in sommige gevallen zo dat het resultaat
zelfs sneller is. Ten tweede is MSIL code in principe platform onafhankelijk. Er bestaat
reeds een CLR die MSIL code op FreeBSD en MacOS 10.2 uitvoert (zie http://msdn.microsoft.com/net/sscli).
Een derde voordeel is dat het maken van een compiler voor een bepaalde taal een stuk
eenvoudiger is. Dit komt omdat deze compiler geen (of weinig) optimalisatie hoeft te
doen. De JIT compiler optimaliseert immers de MSIL code. Optimalisaties van de taal
compiler zouden wel eens averechts kunnen werken. Een laatste voordeel is dat bij MSIL
code gegevens over die code op kunnen slaan, omdat MSIL geen machinetaal is. De CLR kan
deze gegevens, zogenaamde meta data, gebruiken voor het optimalisatieproces, maar de
meta data komt niet terug in de uiteindelijke machinetaal. De meta data is ook uitermate
handig als we componenten gaan maken op basis van bestaande componenten. Door de meta
data kennen we de onderliggende structuur van de code, en kunnen we bestaande code
vervangen door nieuwe code. Zouden we dit niet kunnen, dan zou je een omhulsel moeten
maken dat bepaalde functionaliteit maskeert en opnieuw implementeert. Dat zou uiteindelijk
laag-op-laag-op-laag betekenen, en dat zou een enorme vertraging opleveren bij het
uitvoeren van de applicatie. Het verschil zie je in Afbeelding 2.

Afbeelding 2, Verschil tussen MSIL overerving en binaire overerving
Het laatste onderdeel dat het mogelijk maakt dat er zoveel talen zijn en dat die
naadloos met elkaar kunnen samenwerken is de Class Library van het .NET Framework. In
de Class Library zit de functionaliteit die in iedere taal gebruikt kan worden om
applicaties te maken. Voorheen was het zo dat die functies onderdeel uitmaakt van een
taal, en per taal verschilde. Een goed voorbeeld hiervan zijn functies voor het
manipuleren van datum en tijd, die nu aan het datum/tijd type gekoppeld zijn, en
allerhande wiskundige functies die verzameld zijn in System.Math. In sommige talen
zijn de oude functies hiervoor nog wel beschikbaar, maar die roepen onder de kap de
functies uit het .NET Framework aan.
Overeenkomsten tussen de talen
Alle zaken die ervoor zorgen dat alle talen naadloos met elkaar samen kunnen werken
hebben een grote invloed op hoe de talen van elkaar verschillen. Feitelijk zijn er
geen functionele verschillen en is iedere taal even krachtig. In feite maakt het dus
niet uit welke taal je gebruikt! Het grootste verschil zit in de syntax, zoals je
kunt zien in Listing 1 en Listing 2.
1: for(int i = 1; i <= maxValue; i += 2) {
2: if(i % 3 == 0) {
3: Console.Write(i.ToString());
4: }
5: }
Listing 1, C# voorbeeldcode
1: For i = 1 To maxValue Step 2
2: If i mod 3 = 0 Then
3: Console.Write(i.ToString())
4: End If
5: Next
Listing 2, Voorbeeld uit Listing 2 in VB.NET
Listing 1 en Listing 2 laten dezelfde functionaliteit zien, maar in respectievelijk
C# en VB.NET. Het resultaat is alle getallen vanaf 1 die deelbaar zijn door 2 en 3.
De controle gaat op basis van een teller die door de zogenaamde For-loop opgehoogd
wordt. Bij elke stap wordt de teller met 2 opgehoogd, zodat we alleen getallen krijgen
die deelbaar zijn door 2. Vervolgens hoeven we alleen te controleren of dat getal
deelbaar is door 3. Je ziet dat de C# code een stuk cryptischer is dan de VB.NET code
die meer woorden gebruikt, maar dat de C# code beduidend korter is. Je kunt echt ook
zien dat ze verder functioneel gezien niet echt verschillen. De code in Listing 1 en
Listing 2 zal ook min of meer dezelfde MSIL opleveren, dus is het verschil in snelheid
verwaarloosbaar, helemaal na de optimalisatie door de CLR. Dat de talen functioneel
echt nauwelijks verschillen wordt verder bevestigd door de diverse tutorials die
voorbeelden laten zien in meerdere talen, zoals bijvoorbeeld de ASP.NET training op
de Nederlandse MSDN website (http://www.microsoft.com/netherlands/msdn/aspnet/menu.asp)
en de .NET Framework Quickstarts (http://samples.gotdotnet.com/quickstart/). In beide
worden VB.NET en C# gebruikt, en bij de Quickstarts ook nog JScript en J#. Je kunt dus
in principe iedere taal gebruiken om een applicatie te maken. Het is echter nu al
duidelijk dat C# en VB.NET de twee kerntalen worden.
Verschillen tussen de talen
Het lijkt nu alsof er echt helemaal geen verschil is tussen de verschillende talen
behoudens de syntax. Als dat helemaal waar zou zijn, dan maakt de keuze tussen de
verschillende talen helemaal niets uit. Welke taal je kiest zou dan alleen afhangen
van persoonlijke voorkeur, of omdat in een team van ontwikkelaars een bepaalde taal
gebruikt wordt. Mits je goede afspraken maakt is zelfs dat absoluut geen noodzaak.
Als C# ontwikkelaar is het echter eenvoudig om mee te draaien in een team dat
voornamelijk VB.NET gebruikt, omdat meer dan 95% van de kennis die nodig is om te
kunnen programmeren op het .NET Framework bestaat uit kennis van de functionaliteit
die het framework biedt via de Class Library. Natuurlijk is het even wennen om met
een andere syntax te werken, maar dat is een kwestie van een paar dagen, niet weken.
Toch zijn er wel wat kleine verschillen die de doorslag zullen geven voor een bepaalde
taal. Sommige verschillen zitten in de aanpak van bijvoorbeeld gebeurtenisafhandeling,
maar die verschillen zijn zo klein dat het geen nut heeft die hier te bespreken. Een
groot verschil is echter dat je met C# ook zogenaamde unmanaged code kan schrijven.
Unmanaged code maakt geen gebruik van de faciliteiten die de CLR biedt. Hierdoor is
het mogelijk om zelf het geheugen te manipuleren, wat bijvoorbeeld nodig is bij het
communiceren met drivers en andere systeemonderdelen van Windows die niet als COM
component geïmplementeerd zijn. Omdat de meeste programmeurs hier nooit mee te maken
hebben, doet dit voordeel van C# meestal niet terzake. Belangrijker op dit moment
zijn de faciliteiten van C# om code te documenteren. In alle talen kun je om code te
documenteren commentaar toevoegen aan de code. Buiten de code is deze documentatie
echter niet zichtbaar, waardoor het nodig is documentatie aan te leggen buiten de code.
C# ondersteunt XML-commentaar, een aparte vorm van commentaar die buiten de code wel
zichtbaar is. Het XML-commentaar wordt onder andere door Visual Studio .NET gebruikt
om ontwikkelaars informatie te geven over de functie die ze gebruiken, zoals je kunt
zien in afbeelding 3 waarin het kader informatie geeft over de functie en de
geselecteerde parameter. Deze programmeerhulp komt tijdens het typen automatisch in
beeld.

Afbeelding 3, Programmeerhulp in Visual Studio .NET uit XML-commentaar voor hints
XML-commentaar kan uit de code gekopieerd worden en opgeslagen worden in een apart
bestand. Dit bestand kan dan weer gebruikt worden om help bestanden en dergelijke te
maken. Omdat je op deze manier de documentatie niet hoeft te scheiden van de code,
heeft XML-commentaar vele voordelen. Visual Basic programmeurs klagen dus nu al steen
en been dat ze ook XML-commentaar willen. Naar alle verwachting zal dit bij de
volgende versie ook zeker voor meer programmeertalen beschikbaar zijn, maar
vooralsnog is dit het belangrijkste voordeel van C# ten opzichte van andere talen.
Conclusie
Onder het .NET Framework is de keuze voor een bepaalde taal door de minieme
verschillen voornamelijk subjectief. Redenen die belangrijk zijn is bekendheid met
bepaalde talen, het al bestaan van code in een bepaalde taal, en keuze voor een
bepaalde taal in een team van ontwikkelaars. Zelfs als je een keuze voor een bepaalde
taal gemaakt hebt is overstappen relatief eenvoudig, omdat de meeste kennis het
.NET Framework betreft, en niet een specifieke taal. Wil je meer weten over VB.NET en
C#, dan kun je terecht bij de eerder genoemde links, en bij http://msdn.microsoft.com/library/en-us/vbcon/html/vboriManagedDevelopmentStartPage.asp.
Dit artikel is eerder verschenen in Windows & .NET Magazine Benelux, mei 2003 (huidige naam NetOpus)
|