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. To se liší od proměnné typu odkazu, která obsahuje odkaz na instanci typu. Ve výchozím nastavení se hodnoty proměnných zkopírují při přiřazení, předání argumentu metodě a vrácení výsledku metody. 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 typu odkazu, zkopíruje se při zkopírování instance typu hodnota pouze odkaz na instanci typu odkazu. Kopie i původní instance typu hodnota mají přístup ke stejné instanci typu reference. 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 hodnot a omezení typů

Typ hodnoty může být jedním z těchto dvou 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 jedná o typ hodnoty s možnou hodnotou null.

Pomocí omezení můžete struct určit, že parametr typu je typ hodnoty bez hodnoty null. 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:

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 typu char a 2001 je literál typu int.

  • Konstanty jednoduchých typů můžete deklarovat pomocí klíčového slova const . Není možné mít konstanty jiných typů struktur.

  • Konstantní výrazy, 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#:

Viz také