Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les types valeur et les types référence sont les deux principales catégories de types C#. Une variable d’un type valeur contient une instance du type. Ce comportement diffère d’une variable d’un type référence, qui contient une référence à une instance du type. Par défaut, lors de l’affectation, en passant un argument à une méthode et en retournant un résultat de méthode, vous copiez des valeurs de variable. Dans le cas de variables de type valeur, vous copiez les instances de type correspondantes. L’exemple suivant illustre ce comportement :
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)
Comme le montre l’exemple précédent, les opérations sur une variable de type valeur affectent uniquement cette instance du type valeur, stockée dans la variable.
Si un type valeur contient un membre de données d’un type référence, vous copiez uniquement la référence à l’instance du type de référence lorsque vous copiez une instance de type valeur. La copie et l’instance de type valeur d’origine ont accès à la même instance de type référence. L’exemple suivant illustre ce comportement :
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]
}
}
Notes
Pour rendre votre code moins susceptible d’engendrer des erreurs et plus robuste, définissez et utilisez des types de valeurs immuables. Cet article utilise des types valeur mutables uniquement à des fins de démonstration.
Sortes de types valeur et contraintes de type
Un type valeur peut être l’un des types suivants :
- Type de structure, qui encapsule les données et les fonctionnalités associées.
- Type d’énumération, défini par un ensemble de constantes nommées et qui représente un choix ou une combinaison de choix.
- Déclaration d’union, qui définit un ensemble fermé de types de cas qu’une valeur peut représenter.
Un type valeur pouvant accepter la valeur NullT? représente toutes les valeurs de son type valeur T sous-jacent et une valeur Null supplémentaire. Vous ne pouvez pas affecter null à une variable d’un type valeur, sauf s’il s’agit d’un type valeur nullable.
Utilisez la contrainte pour spécifier qu’un struct paramètre de type est un type valeur non nullable. Les types de structure et d’énumération satisfont à la contrainte struct. Utilisez System.Enum dans une contrainte de classe de base (appelée contrainte d’énumération) pour spécifier qu’un paramètre de type est un type d’énumération.
Types valeurs intégrés
C# fournit les types de valeurs intégrés suivants, également appelés types simples :
- Types numériques intégraux
- Types numériques à virgule flottante
- bool qui représente une valeur booléenne
- char qui représente un caractère Unicode UTF-16
Tous les types simples sont des types de struct. Ils diffèrent des autres types de structs dans montrant qu’ils autorisent certaines opérations supplémentaires :
Vous pouvez utiliser des littéraux pour fournir une valeur d’un type simple.
Par exemple,'A'est un littéral du typechar,2001est un littéral du typeint, et12.34mest un littéral du typedecimal.Vous pouvez déclarer des constantes des types simples à l’aide du mot clé const .
Par exemple, vous pouvez définirconst decimal = 12.34m.
Vous ne pouvez pas déclarer de constantes d’autres types de structs.Les expressions constantes, dont les opérandes sont tous des constantes de type simple, sont évaluées au moment de la compilation.
Un tuple de valeur est un type valeur, mais pas un type simple.
spécification du langage C#
Pour plus d’informations, consultez les sections suivantes de la spécification du langage C# :