C# voor een Java-programmeur

Marco Techniek

Met mijn indiensttreding bij Infi per 1 juni 2020 wisselde ik niet alleen van werkgever, maar ook van programmeertaal. Na 17 jaar Java (en recent natuurlijk ook Kotlin) gebruikt te hebben voor de backend, kwam ik nu in een project, waar C# gebruikt werd. Vol goede moed aan de slag, want van de ene objectgeoriënteerde programeertaal naar de andere: Hoe moeilijk kan het zijn?

Een heel nieuw eco-system.

Zo’n overstap naar een andere taal gaat natuurlijk niet alleen over de taal zelf, maar ook alles er omheen: – Coding Conventions – Libraries – Runtime Environment – Build tools – Deployment Automation

Bij deze een kleine retrospective op 5 maanden C#.

C# vs .NET

Vanuit Java kende ik al het verschil tussen de programmeertaal, die voldoet aan de Java Language Specification en de runtime, die voldoet aan de Java Virtual Machine Specification, In de .NET wereld hebben deze verschillende aspecten ook verschillende namen, die dit minder verwarrend maken. Je hebt C# als programmeer taal en .NET Core als runtime. Net zo als Java naar bytecode wordt gecompileerd, zo wordt C# code gecompileerd naar CIL (Common Intermediate Language). De .NET Core runtime kan dan gebruikt worden voor het uitvoeren van het programma. Er zijn nog meer talen, zoals F# of Visual Basic, die ook naar CIL gecompileerd kunnen worden en er zijn ook nog andere runtimes, zoals Xamarin/Mono.

Project structuur

Een C#-project wordt gevat in een ‘Solution’, welke uit verschillende Projecten kan bestaan. Dit is vergelijkbaar met een Multi-Module Project van Maven, waarbij het verschil is dat de projecten in C# niet van elkaar overerven. Uiteraard kunnen ze wel dependencies op elkaar hebben als ProjectReference.

Ieder project definieert zelf de source version en target version door middel van het zetten van de LangVersion en TargetFramework.

<PropertyGroup>
  <TargetFramework>netstandard2.0</TargetFramework>
  <LangVersion>7.3</LangVersion>
</PropertyGroup>

 

Testen in de project structuur

Één groot verschil is de structuur is dat bij C# de Testen in een specifiek Test-project zitten in plaats van in een aparte directory binnen het project, zoals bij maven gebruikelijk is. Dit Test-project heeft dan dus een dependency op het project of de projecten met de productie-code.

Qua structuur zou je er voor kunnen kiezen om voor ieder project met productiecode ook 1 project te maken met de Test voor dat project, maar dat is niet per se de conventie

De taal zelf

Java en C# lijken in de basis behoorlijk op elkaar qua de structuur classes, interfaces, methoden, fields en operators. Zowel de rekenkundige operatoren als de Booleaanse logische operatoren zijn exact hetzelfde en ook de syntax voor iffor-loops, switch-statements zijn gelijk.

Indien een class een andere class extends of een interface implementeert, in beide gevallen wordt dat aangegeven na een : achter de classnaam zoals: public abstract class Controller : ControllerBase, IActionFilter, IAsyncActionFilter, IDisposable. Je kunt het verschil niet zien, behalve dat de ‘I’-prefix bij interfaces wel een behoorlijke indicator is. Die I is niet verplicht, maar wel onderdeel van de standaard Naming Guidelines

Enums

Wat wel echt anders is, dat zijn de enums. In C# definieert een Enum een set van constante namen voor onderliggende numerieke waarden. De onderliggende waarde zijn standaard ints en worden automatisch genummerd vanaf 0. Je mag echter ook zelf een waarde toewijzen aan individuele constanten of een andere numeriek type kiezen.

De enum kan dus niet een gehele datastructuur representeren.

Een ander gevolg van deze implementatie, merk je voornamelijk bij het switch-statements, waar alsnog een default moet worden toegevoegd, zelfs als alle opties van de Enum als case voorkomen.

LINQ

Met behulp van ‘Language Integrated Query’ (LINQ) wordt het mogelijk om op een uniforme manier queries te doen tegen een datasources. Zo’n datasource kan bijvoorbeeld een XML-bestand, SQL-databases of in memory collecties zijn. De beschikbare keywords hiervoor zijn duidelijk afgeleid van SQL met termen zoals: selectfromwherejoingroup en orderby.

Het werkt met IEnumerable<T> en daardoor lijkt het qua gedrag allemaal behoorlijk zoals de Java Streams API of Kotlin Collections, waarbij de namen in lijn zijn met SQL en dus niet met standaard namen uit de ‘functionele’ paradigma zoals map en filter.

Wil je wel liever met dergelijke namen werken, dan kun je ondersteuning daarvoor toevoegen vanuit: LanguageExt

Struct

Met struct heeft C# wel al een echt Value Type aanboord. Qua gedrag lijken dergelijke structs op Records uit Java 14 of Kotlin Data Classes, zeker als de struct readonly worden gemaakt. Echter als echt Value Type leven de structs dus op de stack.

Code style

Zodra je C#-code gaat lezen als Java-programmeur, dan vallen er meteen een paar dingen op:

  1. De Properties van een Class worden met PascalCasing geschreven, dus een kledingstuk heeft private Color Color ipv private Color color.
  2. De accolade voor het openen van een nieuw blok { staat op de volgende regel.

Daar waar in de Java wereld CheckStyle de tool is voor statisch code analyse, zo zijn er de StyleCopAnalyzers voor .NET.

Conclusie

Als Java programmeur kun je best wel snel redelijk productief worden op een C#-project, maar alle details onder knie krijgen duurt wel iets langer

Een afspraak maken bij ons op kantoor of wil je even iemand spreken? Stuur ons een mail of bel met Jolanda.