Werttypen (C#-Referenz)
Werttypen und Verweistypen sind die beiden Hauptkategorien von C#-Typen. Eine Variable eines Werttyps enthält eine Instanz des Typs. Dies unterscheidet sich von einer Variablen eines Verweistyps, die einen Verweis auf eine Instanz des Typs enthält. Standardmäßig werden die Variablenwerte bei der Zuweisung kopiert, dabei handelt es sich um die Übergabe eines Arguments an eine Methode oder die Rückgabe eines Methodenergebnisses. Im Fall von Werttypvariablen werden die entsprechenden Typinstanzen kopiert. Das folgende Beispiel veranschaulicht dieses Verhalten:
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)
Wie das vorhergehende Beispiel zeigt, wirken sich Vorgänge auf eine Werttypvariable nur auf die in der Variable gespeicherte Instanz des Werttyps aus.
Wenn ein Werttyp einen Datenmember eines Verweistyps enthält, wird beim Kopieren einer Werttypinstanz nur der Verweis auf die Instanz des Verweistyps kopiert. Sowohl die kopierte als auch die ursprüngliche Werttypinstanz haben Zugriff auf dieselbe Verweistypinstanz. Das folgende Beispiel veranschaulicht dieses Verhalten:
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]
}
}
Hinweis
Definieren und verwenden Sie unveränderliche Werttypen, um Ihren Code weniger fehleranfällig und stabiler zu machen. In diesem Artikel werden veränderbare Werttypen nur zur Veranschaulichung verwendet.
Arten von Werttypen und Typeinschränkungen
Ein Werttyp kann einer der zwei folgenden Varianten sein:
- ein Strukturtyp, der Daten und zugehörige Funktionen einschließt
- ein Enumerationstyp, der durch mehrere benannte Konstanten definiert wird und eine Auswahl oder Auswahlmöglichkeiten darstellt
Ein Werttyp, der NULL zulässt wie T?
, stellt alle Werte des zugrunde liegenden Werttyps T
und einen zusätzlichen NULL-Wert dar. Sie können einer Variablen eines Werttyps nicht null
zuweisen, es sei denn, es handelt sich um einen Werttyp,der NULL zulässt.
Sie können die struct
-Einschränkung verwenden, um anzugeben, dass ein Typparameter ein Non-Nullable-Werttyp ist. Sowohl Struktur- als auch Enumerationstypen erfüllen die struct
-Einschränkung. Sie können System.Enum
in einer Basisklasseneinschränkung (die als enum-Einschränkung bezeichnet wird) verwenden, um anzugeben, dass ein Typparameter ein Enumerationstyp ist.
Integrierte Werttypen
C# bietet die folgenden integrierten Werttypen, die auch als einfache Typen bekannt sind:
- Integrale numerische Typen
- Numerische Gleitkommatypen
- bool, der einen booleschen Wert darstellt
- char, der ein Unicode-Zeichen in UTF-16-Codierung darstellt
Alle einfachen Typen sind Strukturtypen und unterscheiden sich von anderen Strukturtypen dadurch, dass sie bestimmte zusätzliche Vorgänge erlauben:
Sie können Literale verwenden, um einen Wert eines einfachen Typs bereitzustellen.
Ist z. B'A'
. ein Literal des Typschar
,2001
ist ein Literal des Typsint
und12.34m
ist ein Literal des Typsdecimal
.Konstanten der einfachen Typen können Sie mit dem Schlüsselwort const deklarieren.
Sie können z. B. definierenconst decimal = 12.34m
.
Es ist nicht möglich, Konstanten anderer Strukturtypen zu haben.Konstante Ausdrücke, deren Operanden alle Konstanten der einfachen Typen sind, werden zur Kompilierzeit ausgewertet.
Ein Werttupel ist ein Werttyp, aber kein einfacher Typ.
C#-Sprachspezifikation
Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation: