21/10/2011
I C#-programmering er egenskaber (properties) en fundamental byggesten for at skabe robust, fleksibel og vedligeholdelsesvenlig kode. De fungerer som en bro mellem en klasses interne data og den ydre verden, hvilket giver os mulighed for at kontrollere adgangen til disse data. Før vi dykker ned i de tekniske detaljer, er det afgørende at forstå princippet om indkapsling, som er kernen i, hvorfor egenskaber er så vigtige. Indkapsling handler om at skjule en klasses 'følsomme' data for direkte adgang og i stedet tilbyde offentlige metoder (via egenskaber) til at læse og opdatere dem. Dette beskytter data mod utilsigtede ændringer og sikrer, at objektets tilstand altid er gyldig.

Grundlaget: Traditionelle Egenskaber med Backing Fields
En traditionel egenskab i C# er tæt knyttet til et privat felt, ofte kaldet et 'backing field'. Dette private felt opbevarer den faktiske værdi, mens den offentlige egenskab giver kontrolleret adgang til feltet gennem to specielle metoder: en get-accessor og en set-accessor.
Lad os se på et klassisk eksempel med en Person-klasse:
public class Person { private string name; // Dette er vores private 'backing field' public string Name // Dette er den offentlige egenskab { get { return name; } // 'get'-accessoren returnerer værdien af det private felt set { name = value; } // 'set'-accessoren tildeler en ny værdi til det private felt } }Her er name et privat felt, som kun kan tilgås inde fra Person-klassen. Name (med stort N) er den offentlige egenskab. Når en anden del af programmet læser værdien, f.eks. Console.WriteLine(myPerson.Name);, kaldes get-accessoren. Når en værdi tildeles, f.eks. myPerson.Name = "Liam";, kaldes set-accessoren. Det specielle nøgleord value i set-accessoren repræsenterer den værdi, der bliver tildelt – i dette tilfælde "Liam".
Hvorfor er denne adskillelse vigtig?
Denne struktur giver os enorm fleksibilitet. I set-accessoren kan vi tilføje logik for at validere de data, der forsøges tildelt. Forestil dig en klasse, der repræsenterer en dato:
public class Dato { private int _maaned; // Backing field for måneden public int Maaned { get => _maaned; set { if (value > 0 && value < 13) // Validering! { _maaned = value; } // Man kunne også kaste en exception her ved ugyldig værdi } } }Med denne kode sikrer vi, at det er umuligt at sætte Maaned til en ugyldig værdi som 13 eller 0. Dette er en kraftfuld måde at opretholde dataintegritet på i dine objekter.
Forenkling med Automatiske Egenskaber (Auto-Properties)
I mange tilfælde har vi ikke brug for speciel logik i vores get- eller set-accessorer. Vi vil blot eksponere et felt. Til disse situationer har C# en meget mere kompakt syntaks, kendt som automatiske egenskaber eller 'auto-properties'.
Eksemplet med Person-klassen kan skrives meget kortere:
public class Person { public string Name { get; set; } // Automatisk egenskab }Dette er alt! Når du bruger denne syntaks, genererer C#-compileren automatisk et skjult, privat backing field for dig bag kulisserne. Koden er lettere at læse og skrive, og funktionaliteten er den samme som i det oprindelige, længere eksempel, så længe der ikke er behov for validering eller anden logik. Dette er den foretrukne metode, når du blot skal opbevare og hente en værdi.

Sammenligning af Egenskabstyper
For at give et klart overblik, er her en tabel, der sammenligner de forskellige tilgange til at definere egenskaber.
| Kriterie | Traditionel Egenskab | Automatisk Egenskab |
|---|---|---|
| Syntaks | Kræver eksplicit definition af privat backing field samt get/set-blokke. | Kortfattet: public Type Navn { get; set; }. |
| Backing Field | Manuelt defineret og navngivet af udvikleren. | Automatisk genereret og skjult af compileren. |
| Logik i Accessorer | Tillader tilpasset logik (f.eks. validering, notifikationer). | Ingen tilpasset logik er mulig direkte i syntaksen. |
| Bedst egnet til | Når du har brug for at kontrollere, hvordan en værdi sættes eller hentes. | Simple dataholdere, hvor der ikke er behov for ekstra logik. |
Avancerede Koncepter og Variationer
Egenskaber i C# er mere end blot get og set. Her er nogle vigtige variationer, du vil støde på.
Skrivebeskyttede Egenskaber (Read-only)
Nogle gange vil du have, at en værdi kun kan sættes, når objektet oprettes, og derefter være uforanderlig. Dette kan opnås på flere måder:
- Kun en
get-accessor:public string Name { get; }. Værdien kan kun sættes i konstruktøren. init-accessor:public string Name { get; init; }. Dette tillader, at værdien sættes via en konstruktør eller en objekt-initialisator (f.eks.new Person { Name = "Liam" };), men den kan ikke ændres bagefter.- Privat
set:public string Name { get; private set; }. Dette betyder, at værdien kan læses udefra, men kun ændres af metoder inde i selve klassen.
Statiske Egenskaber
En egenskab kan erklæres static. Det betyder, at den tilhører selve klassen, ikke en specifik instans af klassen. Dette er nyttigt for data, der er fælles for alle objekter af en type, f.eks. en tæller.
public class Employee { public static int NumberOfEmployees { get; private set; } public Employee() { NumberOfEmployees++; } }Du tilgår den via klassenavnet: Console.WriteLine(Employee.NumberOfEmployees);.
Virtuelle og Abstrakte Egenskaber
I forbindelse med arv kan egenskaber være virtual, hvilket tillader nedarvede klasser at override dem for at levere en specialiseret implementering. En abstract egenskab i en abstrakt klasse definerer ikke en implementering, men tvinger nedarvede klasser til at implementere den.

Ofte Stillede Spørgsmål (FAQ)
Hvad er forskellen på en offentlig egenskab og et offentligt felt?
Et offentligt felt (public string name;) giver direkte, ukontrolleret adgang til data. En offentlig egenskab giver kontrolleret adgang via get- og set-accessorer. Med en egenskab kan du tilføje validering, udløse hændelser eller ændre implementeringen af, hvordan data lagres, uden at bryde koden, der bruger din klasse. Som en generel regel bør felter næsten altid være private, og adgang bør ske via egenskaber.
Hvad gør 'value' nøgleordet præcist?
value er et kontekstuelt nøgleord, der kun er tilgængeligt inden for en set- eller init-accessor. Det repræsenterer den værdi, som kalderen forsøger at tildele til egenskaben. Dets type er den samme som egenskabens type.
Kan en egenskab kun have en 'get'-accessor?
Ja, absolut. En egenskab med kun en get-accessor er skrivebeskyttet (read-only). Dette er meget almindeligt for beregnede egenskaber, hvor værdien afledes af andre data i objektet.
public class Rektangel { public double Laengde { get; set; } public double Bredde { get; set; } // Beregnet, skrivebeskyttet egenskab public double Areal { get { return Laengde * Bredde; } } }Her giver det ikke mening at kunne 'sætte' arealet direkte, da det altid afhænger af længden og bredden.
At mestre brugen af egenskaber er et afgørende skridt mod at skrive professionel og pålidelig C#-kode. Ved at omfavne indkapsling og vælge den rette type egenskab til opgaven – hvad enten den er traditionel, automatisk eller skrivebeskyttet – bygger du software, der er lettere at forstå, vedligeholde og udvide.
Hvis du vil læse andre artikler, der ligner C# Egenskaber: En Komplet Guide til Get og Set, kan du besøge kategorien Sundhed.
