Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.
2023-04-11
Programmeringsspråket C# skiljer på referenstyper och värdetyper. I andra högnivåspråk, som t.ex. Java, har man fram till nyligen bara antagit att egna typer är referenstyper, men som C#-programmerare tvingas man då och då att tänka på skillnaden mellan att skapa egna referenstyper och värdetyper. Konsekvenser för användandet har förändrats en aning över olika versioner av C#, men den grundläggande skillnaden är fortfarande att referenstyper lägger sitt data på heapen medan värdetyper lägger sitt data på stacken.
Det innebär att referenstyper är mer kapabla och mer flexibla, men mindre effektiva än värdetyper. Instanser av båda typerna lever alltså på stacken, men referenstyper heter som de gör för att de inte håller sitt data där – referenstypen håller en referens till sitt data som ligger någonstans på heapen.
Traditionellt har man oftast valt att skapa egna typer som referenstyper i C#, för att de är mer kapabla, särskilt förr. Du har kunnat åstadkomma mer med nyckelordet class än med nyckelordet struct, men idag håller den skillnaden på att suddas ut. Hanteringen av null skiljer sig också mellan dessa, men även det håller på att unifieras, åtminstone på ytan. Tidigare fanns en enkel regel: Instanser av referenstyper var null tills de initierats, medan värdetyper hade ett (annat) defaultvärde tills de initierats. Numera förväntas man deklarera per variabel vilken som kan vara null.
Av följande medlemsvariabler är a och b värdetyper, c och d referenstyper. Endast variabel a har ett värde som inte är null:
private int a;
private int? b;
private string c;
private string? d;
Eftersom a är en värdetyp som inte är nullable, får den sitt default-värde som är 0. Eftersom b är en värdetyp som är nullable, får den sitt default-värde som är null. Både c och d är referenstyper och initieras därför till null, men kompilatorn kommer att bevaka att c får ett värde och att den hanteras som om den alltid är initierad, eftersom den inte är märkt som nullable.
De typer du själv utvecklar bör vara referenstyper (class) om de är komposittyper av andra typer eller om datamängden variabel och gärna lite större. Du bör välja att skapa värdetyper (struct) om instanserna är kortlivade eller utgör en del av en komposittyp. Om instanserna är immutable kan det också vara värt att överväga att låta typen vara en värdetyp.
Del 2/2: Return by reference
Categories: C#
Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!
Leave a Reply