Operator overloading i C#

Tags:    .net c#
Skrevet af Bruger #2730 @ 11.07.2005
Denne artikel omhandler operator overloading i C#. Operator overloading kan være særdeles effektivt når man arbejder med sine egne objekter. Det går i al sin enkelthed ud på at fortælle hvordan man kan eksempelvis lægge to komplekse objekter sammen. Denne artikel antager at læseren ved hvad en klasse og et objekt er samt hvordan man instantierer en klasse til et objekt.

Mine egne komplekse objekter


Det hele starter med at jeg som udvikler sidder og bygger en applikation hvor jeg har flere af mine egne objekter i, og der er i visse tilfælde ønskeligt at kunne eksempelvis addere to af mine objekter. Måden at gøre dette på kan gøres besværligt eller nemt! Den besværlige måde er at lave et objekt der hver gang jeg skal bruge summen af et eller flere objekter, så skal jeg skrive en masse kode der kan håndtere dette. Den nemme derimod er at fortælle mit objekt hvordan den kan addere to objekter. Lad os antage at jeg er ved at bygge en applikation der har til formål at samle arbejdstimer ind for en række ansatte. Jeg laver derfor en timeseddel klasse.
Fold kodeboks ind/udKode 

Dette er en meget simpel klasse til at holde et antal timer der er arbejdet på en bestemt dag. Jeg har lavet en overloaded constructor, grunden til dette er at det giver en bedre overskuelighed senere i min kode. Jeg kan allerede nu, ved at kigge på min klasse se hvordan jeg skal kunne addere to objekter af typen TimeSeddel sammen. Jeg vil addere timerne, naturligvis, så vil jeg sætte dagnavnene sammen i een lang streng adskildt af & tegn. Jeg vil nu inde i min TimeSeddel lave en operator overloading af + tegnet, således jeg kan lægge to TimeSeddel objekter sammen, til dette formål vil jeg lave en ny metode:
Fold kodeboks ind/udKode 

Ovenstående metode er erklæret public således alle andre klasser også kan se den, det er nødvendigt ellers kan en fiktiv klasse som eks. MånedsAfregning ikke tilgå vores overloadede operator og så har vi ikke vundet noget som helst. Desuden er det en statisk metode, dette betyder at der kun kan eksistere een instans af denne metode på tværs af alle objekterne, det betyder også i praksis at vi ikke skal lave en instans af vores TimeSeddel klasse hver gang vi vil addere to timesedler. De næste tre elementer i metoden er måske ikke så gennemskuelige. Det første er det objekt denne metode skal returnere, den anden er nøgleordet for operator overloading. Med dette nøgleord fortæller vi systemet at der nu kommer min egen version af en operator, hvor tredje element så er den egentlige operator vi ønsker at overloade, i dette tilfælde + tegnet. Parameterlisten er rimlig nem at gå til, da det blot er to objekter af typen TimeSeddel. Nu kommer så det afgørende punkt i min overload metode, da jeg skal tage stilling til hvordan min logik omkring denne operator overload skal være. Som tidligere nævnt vil jeg gerne have at det TimeSeddel objekt jeg får tilbage indeholder dagene konkateneret med & tegn og timerne blot summeret. Dette implementerer jeg så og returnerer det nye objekt (det er her jeg har valgt at bruge den default constructor for overskuelighedens skyld). Det der nu er tilbage for at teste denne overload er rent faktisk at kalde noget kode og se om det virker.
Fold kodeboks ind/udKode 

Ovenstående kode opretter to TimeSeddel objekter for henholdsvis mandag og tirsdag og sætter værdien af Timer properties til henholdsvis 7 og 8. I tredje linie opretter vi så et TimeSeddel objekt der indeholder alle dagene sammenlagt. Det eneste vi mangler for lige at teste om det virker er at skrive det ud. I stedet for at skrive hver enkelt variabel ud bliver vi i overload-tankegangen og overrider objektets ToString() metode til at kunne give os de informationer vil vil have. At override en simpel metode kan Visual Studio hjælpe os med, hvis man starter med at taste "protected override..." vil den straks vise en liste af de metoder der er mulighed for at override. Vi vælger objektets ToSTring() metode og Visual Studio autogenerer straks koden til at gøre dette med:
Fold kodeboks ind/udKode 

Det eneste vi vil gøre er at slette linien mellem tuborg klammerne og erstatte den med vores egen (linien gør blot at den kalder ToString() metoden på det objekt man har nedarvet fra). Den midterste linie erstatter vi med denne linie, der viser en mere teksturel beskrivelse af vores TimeSeddel objekt.
Fold kodeboks ind/udKode 

Nu kan vi endelig på en nem måde skrive vores objekt ud, nu vil vi modificere den kode vi skrev tidligere til at skrive vores TimeSeddel objekt ud, dette gøres ved at bruge vores nye overridden metode ToString().
Fold kodeboks ind/udKode 

Når vi så kører vores program vil vi få et output der ser ud som vist her:
Dage: Mandag & Tirsdag Timer: 15
Som tidligere skrevet kan operator overloading lette en masse arbejde for os. I dette simple eksempel er det kun strings og integers og kun to properties, men det kunne være meget værre!

Overloade overloadede operatorer


Bare overskriften er ved at slå knude på tungen, men der er nu ikke så vanskeligt. Vi ønsker lige mere fleksibilitet i vores system, vi vil fx. gerne have at vi kan addere nogle timer til et objekt der er oprettet i forvejen. Til dette formål kan vi lave en overloadet version af vores operator overloader der tager et TimeSeddel objekt og et integer der angiver det antal timer vi skal have lagt til vores TimeSeddel. Ganske som med almindelig metode overload laver vi da bare en ny metode der tager andre parametre og har en lidt anderledes logik
Fold kodeboks ind/udKode 

Modificerer vi samtidig vores kode der tester dette kommer til eksempelvis til at se således ud:

Dage: Tirsdag Timer: 14
Dage: Mandag & Tirsdag Timer: 21

koden til at skrive ud med ser nu således ud
Fold kodeboks ind/udKode 


Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (6)

User
Bruger #5779 @ 12.07.05 08:42
Udemærket artikel. :)
User
Bruger #7334 @ 14.07.05 13:31
Operator+ bør IMHO være:

public static TimeSeddel operator + (TimeSeddel timeseddel1, int ekstratimer)
{
TimeSeddel nytimeseddel = new TimeSeddel(timeseddel1.dag, timeseddel1.timer);
nytimeseddel.timer+=ekstratimer;
return nytimeseddel;
}


I eksemplet:
TimeSeddel nyTirsdag = tirsdag + 6;
bliver variablen tirsdag også rettet (jeg ville ikke forvente nyTirsdag == tirsdag efter udførelsen)
User
Bruger #2730 @ 15.07.05 08:33
Korrekt, den havde jeg ikke lige spottet, tak for hjælpen :-)
User
Bruger #7334 @ 15.07.05 08:37
Det var så lidt :-)
User
Bruger #10009 @ 01.06.06 13:28
Synes det er en rigtig god og nyttig lille artikel :)
User
Bruger #285 @ 15.01.07 20:15
Ganske udemærket artikel. Lige en lille ting - du skriver kort i artiklen mht. override af ToString, at man kan skrive "protected override", men der skulle nok stå "public override", som du også skriver senere. Derudover (før den skulle give 5), skal du nok lige løfte tommelfingeren overfor at bruge operator overloading for heftigt; det kan være svært at læse en andens kode, hvis operatorerne er overloadet på en underlige måde, og det kan gøre debug meget svært (jeg kunne jo sagtens definere + til at være at den skulle afrunde timeantallet eller hvad nu af sjove ting, man kunne finde på). Men som sagt: god artikel!
Du skal være logget ind for at skrive en kommentar.
t