ASPNL logo (1 kb)
Saturday, February 04, 2012




Microsoft MVP

.NET Codewise Community
<< vorige | overzicht | volgende >>

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)

<< vorige | ^ naar boven | overzicht | volgende >>
copyright 2000-2007 ASPNL