ASPNL logo (1 kb)
Tuesday, February 09, 2010




Microsoft MVP

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

The Vision Column - De aftrap

The Vision Column wordt verzorgd door ontwikkelaars van The Vision Web (tegenwoordig Ordina).

Door Walter van Parera
25 april 2005

Daar is hij dan. De eerste in een hopelijk lange reeks van columns over .NET, voor en door de Vision Webbers, ter inspiratie en motivatie van allen. Toen ik mij spontaan aanbood om dit eerste epistel te vervaardigen vroeg ik mij een seconde later af waar ik het geheel in godsnaam mee ging vullen. Echter, na een klein idee en wat klassiek speurwerk rolt zo’n verhaal vanzelf jouw kant op. Als je dan uit pure nieuwsgierigheid nog wat verder graaft…

Om in de onsterfelijke woorden van journalist Argus uit de verzamelde werken van Ollie B. Bommel te spreken: "Daar zit een scherp stukje in!".

De historie

Bijna twee jaar geleden alweer hebben we binnen The Vision Web voor het eerst een poging gewaagd om de Coding Standards van The Vision Web nieuw leven in te blazen door een dikke recommendation te schrijven. Uiteindelijk werden hierbij de coding standards & practices van Microsoft plus de eigen ervaringen gebundeld in een nog steeds vadsige berg pagina’s. Op zich komen de TVW Coding Standards dus voor 95% overeen met wat Microsoft hierover zegt, in ieder geval voor het C#/.NET deel.

Desalniettemin zijn er nog genoeg zaken rondom coding standards die ook binnen The Vision Web nog wel eens voor het voetlicht gehaald kunnen worden. Een typisch voorbeeld daarvan is gebruik en naamgeving van member variabelen. Omdat Microsoft hier geen duidelijk standpunt in heeft genomen is dit ook typisch een probleem dat op het Web ook gespreksmateriaal vormt voor vele discussies en blogs.

What’s in a name…

Professionals in .NET gebruiken een onwaarschijnlijke hoeveelheid aan vormen om member variabelen te onderscheiden van de rest van de code. Algehele consensus is er in ieder geval over het niet meer gebruiken van Hongaarse notatie voor prefixen middels data typeringen (de fameuze strMemberVariable of sMemberVariable). De originele noodzaak hiervoor stamde uit het gebrek aan leesbaarheid en tevens het onvermogen van compilers om een typering af te dwingen. Omdat deze noodzaak is verdwenen lag het voor de hand om de onderhoudbaarheid te verbeteren en dit soort prefixen te laten voor wat ze zijn. Tevens is inmiddels camelCasing als standaard geaccepteerd. Echter, er is dan nog steeds een grote hoeveelheid mogelijkheden in definitie en aanspreken van die variabelen:

1]      memberVariable = ...
2]      m_MemberVariable = ...
3]      m_memberVariable = ...
4]      _MemberVariable = ...
5]      memberVariable = ...
6]      this.memberVariable = ...
7]      this.m_MemberVariable = ...
8]      this.m_memberVariable = ...
9]      this._MemberVariable = ...
10]      this._memberVariable = ...

Welke is nu aanbevolen? Private members worden vooral gebruikt voor het vasthouden van state voor public visible properties. Een voor de hand liggende constructie binnen C# zou dan zijn om memberVariable voor de private member en MemberVariable voor de property te kiezen.

Echter, wanneer ook VB.NET in de vergelijking betrokken wordt krijgen we een probleem, immers, VB.NET is niet case-sensitive. Er is dus behoefte aan wat meer onderscheidend vermogen, te verkrijgen middels een prefix. Exit gevallen 1 en 6…

Vanuit het verleden (VB6) werd vooral de m_ gebruikt. Reden was simpelweg dat de compiler geen variabelen met _ prefix accepteerde. Wanneer je uitgaat van het principe dat je zo min mogelijk code zou moeten hebben, is de m dus gewoon overbodig. Exit de vormen 2, 3, 7 en 8.

De vormen 4 en 9 zijn enigszins onduidelijk. Wanneer je snel leest (denk aan mensen met slechte ogen, ;-)) dan lijken deze vormen al snel op hun property equivalenten (vooral variant 4 omdat daar het “gat” niet opvalt). Daarnaast is er van de camelCasing ook niet echt veel over. Exit gevallen 4 en 8…

De overblijvende constructies zijn 5 en 10. In eerste instantie is het gebruik van het keyword this in zekere zin overbodig. Echter, wanneer je iets verder kijkt dan je neus lang is, dan zie je dat de bijbehorende properties dit onderscheidende vermogen wel sterk nodig hebben. Je kunt op die manier de property this.MemberVariable = … goed onderscheiden van een willekeurige static object of locale variabele. Het ligt dan voor de hand om consequent te zijn en tevens this._memberVariable uit te voeren al zal het gat in het midden sommigen voorkomen als lelijk. Echter, lelijk valt op en is dus duidelijk! (nietwaar Sugarlee Hooper?).

Belangrijk punt is nog wel dat protected member variabelen om CLS compliant te zijn niet mogen beginnen met een “_”. Bovenstaande geld derhalve puur voor private member variabelen.

En de reus uit Redmond?

Ik zou mezelf niet zijn als ik hier gestopt zou zijn (moet ook om mijn rep denken). Het is natuurlijk interessant om erachter te komen hoe de code van het .NET framework hier nu zelf mee omgaat. Een stuk van de puzzel is op te lossen door het bekijken van de Intermediate Language en te constateren hoe de variabelen benoemd zijn. Echter, je ziet dan weinig terug van de eigenlijke gebruikswijze. Op zich kun je natuurlijk met tools als Reflector of Anakrino aan de slag om via reflectie en IL te decompileren, maar je krijgt dan niet de originele naamgeving terug.

Desondanks kunnen we via een omweg toch een groot deel van de originele source van de framework classes bekijken. De Shared Source Common Language Infrastructure van Microsoft is een archief van sources om een werkende implementatie van de ECMA CLI en de ECMA C# language specification te verkrijgen. De Common Language Infrastructure (CLI) is daarin dus de ECMA standaard die het hart van het .NET Framework beschrijft. Deze implementatie is ontstaan vanuit dezelfde codebase als de commerciële implementatie van .NET. Hoewel onderdelen natuurlijk compleet anders zijn geworden is een groot deel nog steeds een directe representatie van code van het echte platform.

We kunnen nu de proef op de som nemen en kijken wat binnen deze codebase nu de meest gebruikte constructies zijn. De downloadable codebase bestaat uit 3238 C# files met class definities, struct definities, etc.. Ik begon dus met het opentrekken van een willekeurige file en ziedaar: een keurig gebruik van de _memberVariable constructie!

Door alle files met een simpele search te scannen kunnen we zien hoeveel van de 3238 stuks welke constructies gebruiken:

Type Aantal
private int _/ private string _ 57/46
Private int m_/ private string m_ 34/31
this._ 18
this.m_ 51
int _ 104
int m_ 82

Hmmm… dat schiet niet erg op. Laten we maar eens wat files open trekken want een echte knopenhakker is dit nog niet geworden. Hoe komt het trouwens dat we sowieso weinig resultaten terugkrijgen? Huh? Wat zien wij? …internal static String s_Encoding, internal String _Quot, string m_path, private int hi, this._ticks....

En verder ontbrekende coding comments, rare coding comments, vreemde whitespace, etc.. FxCop zou ter plekke een hartstilstand krijgen! Een typisch geval van “Do as I say but don’t do as I do”?

Ik zal maar zeggen: Gebruik je gezonde verstand. Deze files zijn elk op zichzelf natuurlijk vrij consistent, maar als een bundel eigenlijk een rommeltje van standaards. "Ter lering ende vermaak" zullen we maar zeggen. Trek je eigen conclusies maar hoe je er mee om moet gaan.

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