Waardetypen (C#-verwijzing)
Waardetypen en verwijzingstypen zijn de twee hoofdcategorieën van C#-typen. Een variabele van een waardetype bevat een exemplaar van het type. Dit verschilt van een variabele van een verwijzingstype, die een verwijzing naar een exemplaar van het type bevat. Standaard worden bij toewijzing een argument doorgegeven aan een methode en een methoderesultaat geretourneerd, variabele waarden gekopieerd. In het geval van variabelen van het waardetype worden de bijbehorende typeinstanties gekopieerd. In het volgende voorbeeld ziet u dat gedrag:
using System;
public struct MutablePoint
{
public int X;
public int Y;
public MutablePoint(int x, int y) => (X, Y) = (x, y);
public override string ToString() => $"({X}, {Y})";
}
public class Program
{
public static void Main()
{
var p1 = new MutablePoint(1, 2);
var p2 = p1;
p2.Y = 200;
Console.WriteLine($"{nameof(p1)} after {nameof(p2)} is modified: {p1}");
Console.WriteLine($"{nameof(p2)}: {p2}");
MutateAndDisplay(p2);
Console.WriteLine($"{nameof(p2)} after passing to a method: {p2}");
}
private static void MutateAndDisplay(MutablePoint p)
{
p.X = 100;
Console.WriteLine($"Point mutated in a method: {p}");
}
}
// Expected output:
// p1 after p2 is modified: (1, 2)
// p2: (1, 200)
// Point mutated in a method: (100, 200)
// p2 after passing to a method: (1, 200)
Zoals in het voorgaande voorbeeld wordt weergegeven, zijn bewerkingen op een waardetypevariabele alleen van invloed op dat exemplaar van het waardetype, opgeslagen in de variabele.
Als een waardetype een gegevenslid van een verwijzingstype bevat, wordt alleen de verwijzing naar het exemplaar van het verwijzingstype gekopieerd wanneer een exemplaar van het waardetype wordt gekopieerd. Zowel het exemplaar van het kopie- als het oorspronkelijke waardetype-exemplaar heeft toegang tot hetzelfde exemplaar van het verwijzingstype. In het volgende voorbeeld ziet u dat gedrag:
using System;
using System.Collections.Generic;
public struct TaggedInteger
{
public int Number;
private List<string> tags;
public TaggedInteger(int n)
{
Number = n;
tags = new List<string>();
}
public void AddTag(string tag) => tags.Add(tag);
public override string ToString() => $"{Number} [{string.Join(", ", tags)}]";
}
public class Program
{
public static void Main()
{
var n1 = new TaggedInteger(0);
n1.AddTag("A");
Console.WriteLine(n1); // output: 0 [A]
var n2 = n1;
n2.Number = 7;
n2.AddTag("B");
Console.WriteLine(n1); // output: 0 [A, B]
Console.WriteLine(n2); // output: 7 [A, B]
}
}
Notitie
Als u uw code minder foutgevoelig en robuuster wilt maken, definieert en gebruikt u onveranderbare waardetypen. In dit artikel worden alleen veranderlijke waardetypen gebruikt voor demonstratiedoeleinden.
Soorten waardetypen en typebeperkingen
Een waardetype kan een van de volgende twee soorten zijn:
- een structuurtype, dat gegevens en gerelateerde functionaliteit inkapselt
- een opsommingstype, dat wordt gedefinieerd door een set benoemde constanten en een keuze of een combinatie van keuzen vertegenwoordigt
Een waardetype T?
dat null kan worden gebruikt, vertegenwoordigt alle waarden van het onderliggende waardetype T
en een extra null-waarde. U kunt niet toewijzen null
aan een variabele van een waardetype, tenzij dit een null-waardetype is.
U kunt de struct
beperking gebruiken om op te geven dat een typeparameter een niet-null-waardetype is. Zowel structuur- als opsommingstypen voldoen aan de struct
beperking. U kunt in een basisklassebeperking (ook wel de enumbeperking genoemd) gebruiken System.Enum
om op te geven dat een typeparameter een opsommingstype is.
Ingebouwde waardetypen
C# biedt de volgende ingebouwde waardetypen, ook wel eenvoudige typen genoemd:
- Integrale numerieke typen
- Numerieke typen drijvende komma
- bool die een Booleaanse waarde vertegenwoordigt
- teken dat een Unicode UTF-16-teken vertegenwoordigt
Alle eenvoudige typen zijn structuurtypen en verschillen van andere structuurtypen omdat ze bepaalde aanvullende bewerkingen toestaan:
U kunt letterlijke waarden gebruiken om een waarde van een eenvoudig type op te geven.
Is bijvoorbeeld'A'
een letterlijke letterlijke van het typechar
,2001
is een letterlijke van het typeint
en12.34m
is een letterlijke van het typedecimal
.U kunt constanten van de eenvoudige typen declareren met het sleutelwoord const .
U kunt bijvoorbeeld definiërenconst decimal = 12.34m
.
Het is niet mogelijk om constanten van andere structuurtypen te hebben.Constante expressies, waarvan operanden alle constanten van de eenvoudige typen zijn, worden geëvalueerd tijdens het compileren.
Een waarde-tuple is een waardetype, maar niet een eenvoudig type.
C#-taalspecificatie
Zie de volgende secties van de C#-taalspecificatie voor meer informatie: