The Vision Column - Fields of Properties?
The Vision Column wordt verzorgd door ontwikkelaars van
The Vision Web (tegenwoordig Ordina).
Door Michiel van Otegem
3 mei 2005
In navolging van Walter van Parera's uitgebreide relaas over naamgeving en het gebruik van "this"
(zie The Vision Column - De aftrap), vervolg
ik deze column met een andere heilige oorlog: het gebruik van Fields en Properties. Hierover zijn
zoveel meningen als dat er (.NET) ontwikkelaars zijn, ondanks dat hierover een duidelijke
richtlijn is van Microsoft. In de Design Guidelines for Class Library Developers
(http://msdn.microsoft.com/library/en-us/cpgenref/html/cpconNETFrameworkDesignGuidelines.asp)
staat in de Field Usage Guidelines (http://msdn.microsoft.com/library/en-us/cpgenref/html/cpconfieldusageguidelines.asp)
duidelijk wanneer Fields wel/niet een goed idee zijn.
Voordat ik wat dieper op de guidelines in ga eerst nog even een opfrissertje. Als we het hebben
over een Field, dan hebben we het in feite over een variabele die we definiëren binnen een class,
als volgt:
1: public class MyClass
2: {
3: public int MyInt;
4: }
Een Field kan uiteraard public, protected, private enz. zijn, en zo nodig static. Een Property
daarentegen is zo'n ding met een get en een set:
1: public class MyClass
2: {
3: private int _myInt;
4:
5: public int MyInt
6: {
7: set
8: {
9: return this._myInt;
10: }
11: get
12: {
13: this._myInt = value;
14: }
15: }
16: }
Functioneel gezien zijn Field en Property zoals ik ze hier gedefinieerd heb gelijk aan elkaar.
Het enige dat je dus aan het doen bent is behoorlijk wat (schijnbaar) overbodige code schrijven.
Waarom 12 regels code als het ook met één kan, toch? Nou, toch niet... De voorschriften zeggen
dat je nooit public of protected Fields hebt, tenzij de waarde altijd constant is (const, dan wel
static read-only). De vraag is nu natuurlijk "Waarom is dit belangrijk?".
De belangrijkste reden is dat een Property logica kan bevatten voor bijvoorbeeld het valideren
van een opgegeven waarde. Een Field is niets meer dan een variabele, dus je hebt geen controle
over wat de buitenwereld erin stopt. Nu hoor ik je denken "maar dan verander ik m'n Field toch
gewoon in een Property als ik die logica nodig heb?". Dat zou kunnen, maar daarmee "overtreed"
je weer andere regels. Het ontwikkelparadigma van .NET, en ook al van COM overigens, is namelijk
component gebaseerd. Het idee is dat je applicaties opdeelt in meerdere componenten (assemblies),
die volgens een interface met elkaar communiceren. Als deze interface niet door de ontwikkelaar
gedefinieerd is, is deze overigens toch impliciet aanwezig. Een interface is eigenlijk een
afspraak waarin is vastgelegd is hoe een component aangeroepen kan worden. En nu komt de crux:
voor een interface zijn een Field en een Property niet gelijk aan elkaar. Door van een Field een
Property te maken verandert dus de interface, en moet alles dat gebruik maakt van je component
opnieuw gecompileerd worden. Het idee van component gebaseerde ontwikkeling is echter dat
componenten onafhankelijk van elkaar ontwikkeld moeten kunnen worden.
Er zit overigens ook nog wel een praktische kant aan de zaak. In een Property kun je breakpoints
zetten en kun je debug- of trace-statements plaatsen. Bij een Field daarentegen kan dat niet.
Een mogelijk argument vóór Fields zou de snelheid kunnen zijn. Het is niet gek om te denken dat
de Property zoals eerder gedefinieerd langzamer in gebruik is dan het gedefinieerde Field. De
.NET JIT-compiler is echter zo slim dat de uiteindelijke machine code hetzelfde is, en anders is
het verschil in snelheid verwaarloosbaar.
Het andere argument vóór Fields, minder regels code, is voor een ervaren programmeur nauwelijks
een argument. Je kunt via de Class-browser Properties aanmaken die alleen maar ingevuld hoeven te
worden, en je kunt ook een complete definitie opslaan in je toolbox en je code in slepen.
Als je dus nog eens een class maakt, en dat is natuurlijk vaak, zorg dat je nooit public of
protected Fields hebt. Gebruik voor die class-members altijd Properties, ook al lijkt dat wat
overbodig. Visual Studio 2005 biedt overigens refactoring ondersteuning waardoor je makkelijk je
Fields tot Properties kunt promoveren... dat scheelt alvast wat type werk.
|