Typy hodnot (referenční dokumentace jazyka C#)
Typy hodnot a odkazové typy jsou dvě hlavní kategorie typů jazyka C#. Proměnná typu hodnoty obsahuje instanci typu. Liší se od proměnné typu odkazu, která obsahuje odkaz na instanci typu. Ve výchozím nastavení se při přiřazení předá argument metodě a vrátí výsledek metody, hodnoty proměnných se zkopírují. V případě proměnných typu hodnota se zkopírují odpovídající instance typu. Následující příklad ukazuje toto chování:
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)
Jak ukazuje předchozí příklad, operace s proměnnou typu hodnoty ovlivňují pouze tuto instanci typu hodnoty uloženou v proměnné.
Pokud typ hodnoty obsahuje datový člen referenčního typu, zkopíruje se při zkopírování instance typu hodnoty pouze odkaz na instanci typu odkazu. Kopie i původní instance typu hodnota mají přístup ke stejné instanci typu odkazu. Následující příklad ukazuje toto chování:
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]
}
}
Poznámka:
Pokud chcete, aby byl kód méně náchylný k chybám a robustnější, definujte a používejte neměnné typy hodnot. Tento článek používá proměnlivé typy hodnot pouze pro demonstrační účely.
Typy typů hodnot a omezení typů
Typ hodnoty může být jedním ze dvou následujících typů:
- typ struktury, který zapouzdřuje data a související funkce
- typ výčtu, který je definován sadou pojmenovaných konstant a představuje volbu nebo kombinaci voleb.
Typ T?
hodnoty s možnou hodnotou null představuje všechny hodnoty jeho základního typu T
hodnoty a další hodnotu null. Nelze přiřadit null
proměnnou typu hodnoty, pokud se nejedná o typ hodnoty s možnou hodnotou null.
Pomocí omezení můžete struct
určit, že parametr typu je nenulový typ hodnoty. Typy struktur i výčtů struct
splňují omezení. V omezení základní třídy (označované jako omezení výčtu) můžete určitSystem.Enum
, že parametr typu je typ výčtu.
Předdefinované typy hodnot
Jazyk C# poskytuje následující předdefinované typy hodnot, označované také jako jednoduché typy:
- Integrální číselné typy
- Číselné typy s plovoucí desetinou čárkou
- bool představující logickou hodnotu
- char , který představuje znak Unicode UTF-16
Všechny jednoduché typy jsou typy struktur a liší se od jiných typů struktury, které umožňují určité další operace:
Literály můžete použít k zadání hodnoty jednoduchého typu.
Je například'A'
literál typuchar
,2001
je literál typuint
a12.34m
je literál typudecimal
.Konstanty jednoduchých typů můžete deklarovat pomocí klíčového slova const .
Můžete například definovatconst decimal = 12.34m
.
Není možné mít konstanty jiných typů struktury.Výrazy konstant, jejichž operandy jsou všechny konstanty jednoduchých typů, se vyhodnocují v době kompilace.
Řazená kolekce hodnot je typ hodnoty, ale ne jednoduchý typ.
specifikace jazyka C#
Další informace najdete v následujících částech specifikace jazyka C#: