Типы значений (справочник по C#)Value types (C# reference)

Типы значений и ссылочные типы — это две основные категории типов C#.Value types and reference types are the two main categories of C# types. Переменная типа значения содержит экземпляр типа.A variable of a value type contains an instance of the type. Это отличается от переменной ссылочного типа, которая содержит ссылку на экземпляр типа.This differs from a variable of a reference type, which contains a reference to an instance of the type. По умолчанию при назначении, передаче аргумента в метод и возврате результата метода копируются значения переменных.By default, on assignment, passing an argument to a method, and returning a method result, variable values are copied. В случае переменных типа значения копируются соответствующие экземпляры типа.In the case of value-type variables, the corresponding type instances are copied. В следующем примере продемонстрировано такое поведение.The following example demonstrates that behavior:

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)

Как показано в предыдущем примере, операции с переменной типа значения влияют только на этот экземпляр типа значения, хранящийся в переменной.As the preceding example shows, operations on a value-type variable affect only that instance of the value type, stored in the variable.

Если тип значения содержит элемент данных ссылочного типа, то при копировании экземпляра типа значения копируется только ссылка на экземпляр ссылочного типа.If a value type contains a data member of a reference type, only the reference to the instance of the reference type is copied when a value-type instance is copied. Как скопированный, так и исходный экземпляр типа значения имеют доступ к одному и тому же экземпляру ссылочного типа.Both the copy and original value-type instance have access to the same reference-type instance. В следующем примере продемонстрировано такое поведение.The following example demonstrates that behavior:

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]
    }
}

Примечание

Чтобы сделать код менее подверженным ошибкам и более надежным, определите и используйте неизменяемые типы значений.To make your code less error-prone and more robust, define and use immutable value types. В этой статье изменяемые типы значений используются только в демонстрационных целях.This article uses mutable value types only for demonstration purposes.

Виды типов значенийKinds of value types

Тип значения может относится к одному из двух следующих видов:A value type can be one of the two following kinds:

  • тип структуры, который инкапсулирует данные и связанные функции;a structure type, which encapsulates data and related functionality
  • тип перечисления, который определяется набором именованных констант и представляет выбор или сочетание вариантов для выбора.an enumeration type, which is defined by a set of named constants and represents a choice or a combination of choices

Тип значений T?, допускающий значение NULL, представляет все значения своего базового типа значения T, а также дополнительное значение NULL.A nullable value type T? represents all values of its underlying value type T and an additional null value. Вы не можете назначить null переменной типа значения, если только это не тип, допускающий значение NULL.You cannot assign null to a variable of a value type, unless it's a nullable value type.

Встроенные типы значенийBuilt-in value types

C# предоставляет следующие встроенные типы значений, которые также называются простыми типами.C# provides the following built-in value types, also known as simple types:

Все простые типы являются типами структур и отличаются от других типов структур тем, что разрешают некоторые дополнительные операции.All simple types are structure types and differ from other structure types in that they permit certain additional operations:

  • Литералы можно использовать для предоставления значения простого типа.You can use literals to provide a value of a simple type. Например, 'A' — это литерал типа char, а 2001 — литерал типа int.For example, 'A' is a literal of the type char and 2001 is a literal of the type int.

  • Константы простых типов можно объявить с помощью ключевого слова const.You can declare constants of the simple types with the const keyword. Невозможно использовать константы других типов структур.It's not possible to have constants of other structure types.

  • Константные выражения, операнды которых являются константами простых типов, вычисляются во время компиляции.Constant expressions, whose operands are all constants of the simple types, are evaluated at compile time.

Начиная с версии 7.0 в языке C# поддерживаются кортежи значений.Beginning with C# 7.0, C# supports value tuples. Кортеж значений — это тип значения, не являющийся простым.A value tuple is a value type, but not a simple type.

Спецификация языка C#C# language specification

Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:For more information, see the following sections of the C# language specification:

См. такжеSee also