Types valeur du système de type commun

Mise à jour : novembre 2007

La plupart des langages de programmation fournissent des types de données intégrés, tels que des nombres entiers et des nombres à virgule flottante, qui sont copiés lorsqu'ils sont passés comme arguments (c'est-à-dire qu'ils sont passés par valeur). Dans le .NET Framework, ceux-ci sont qualifiés de types valeur. Le runtime prend en charge deux genres de types valeur :

  • Types valeur intégrés

    Le .NET Framework définit des types valeur intégrés, tels que System.Int32 et System.Boolean, qui correspondent et sont identiques aux types de données primitifs utilisés par des langages de programmation.

  • Types valeur définis par l'utilisateur

    Votre langage permet de définir vos propres types valeur, qui dérivent de System.ValueType ou System.Enum. Si vous souhaitez définir un type représentant une petite valeur, telle qu'un nombre complexe (utilisant deux nombres à virgule flottante), vous pouvez éventuellement choisir de le définir comme un type valeur parce que vous pouvez passer efficacement le type valeur par valeur. Si le type que vous définissez serait passé plus efficacement par référence, il convient plutôt de le définir comme une classe.

Pour obtenir des informations spécifiques aux énumérations, consultez Énumérations dans le système de type commun.

Les types valeur sont stockés aussi efficacement que les types primitifs, et vous pouvez appeler des méthodes sur ceux-ci, notamment les méthodes virtuelles définies sur les classes System.Object et System.ValueType, ainsi que toute méthode définie sur le type valeur lui-même. Vous pouvez créer des instances de types valeur, les passer comme paramètres, les stocker comme variables locales ou les stocker dans un champ d'un autre type valeur ou objet. Les types valeur ne présentent pas la charge mémoire associée au stockage d'une instance d'une classe et ne nécessitent pas de constructeurs.

Pour chaque type valeur, le runtime fournit un type boxed qui est une classe ayant le même état et le même comportement que le type valeur. Certains langages imposent l'utilisation d'une syntaxe spéciale lorsque le type boxed est requis ; d'autres utilisent automatiquement le type boxed lorsqu'il est nécessaire. Lorsque vous définissez un type valeur, vous définissez le type boxed et le type unboxed.

Les types valeur peuvent avoir des champs, des propriétés et des événements. Ils peuvent également avoir des méthodes statiques et non statiques. Lorsqu'ils sont boxed, ils héritent des méthodes virtuelles de System.ValueType, et ils peuvent implémenter zéro ou plusieurs interfaces.

Les types valeur sont sealed, ce qui signifie qu'aucun autre type ne peut en être dérivé. Cependant, vous pouvez définir des méthodes virtuelles directement sur le type valeur, et ces méthodes peuvent être appelées sur la forme boxed ou unboxed du type. Bien que vous ne puissiez pas dériver un autre type à partir d'un type valeur, vous pourriez définir des méthodes virtuelles sur un type valeur lorsque vous utilisez un langage dans lequel il est plus pratique de travailler avec des méthodes virtuelles qu'avec des méthodes non virtuelles ou statiques.

L'exemple suivant montre comment construire un type valeur pour des nombres complexes.

Option Strict
Option Explicit

Imports System

' Value type definition for a complex number representation.
Public Structure Complex
    Public r, i As Double
    
    ' Constructor.
    Public Sub New(r As Double, i As Double)
        Me.r = r
        Me.i = i
    End Sub
    
    ' Returns one divided by the current value.
    Public ReadOnly Property Reciprocal() As Complex
        Get
            If r = 0.0 And i = 0.0 Then
                Throw New DivideByZeroException()
            End If 
            Dim div As Double = r * r + i * i
            Return New Complex(r / div, -i / div)
        End Get
    End Property
    
    
    ' Conversion methods.
    Public Shared Function ToDouble(a As Complex) As Double
        Return a.r
    End Function

    Public Shared Function ToComplex(r As Double) As Complex
        Return New Complex(r, 0.0)
    End Function

    ' Basic unary methods.
    Public Shared Function ToPositive(a As Complex) As Complex
        Return a
    End Function

    Public Shared Function ToNegative(a As Complex) As Complex
        Return New Complex(-a.r, -a.i)
    End Function

    ' Basic binary methods for addition, subtraction, multiplication, and division.
    Public Shared Function Add(a As Complex, b As Complex) As Complex
        Return New Complex(a.r + b.r, a.i + b.i)
    End Function

    Public Shared Function Subtract(a As Complex, b As Complex) As Complex
        Return New Complex(a.r - b.r, a.i - b.i)
    End Function

    Public Shared Function Multiply(a As Complex, b As Complex) As Complex
        Return New Complex(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r)
    End Function

    Public Shared Function Divide(a As Complex, b As Complex) As Complex
        Return Multiply(a, b.Reciprocal)
    End Function

    ' Override the ToString method so the value appears in write statements.
    Public Overrides Function ToString As String
        Return String.Format("({0}+{1}i)", r, i)
    End Function
End Structure

' Entry point.
Public Class ValueTypeSample
    
    Public Shared Sub Main()
        Dim a As New Complex(0, 1)
        Dim b As New Complex(0, - 2)
        
        Console.WriteLine()
        Console.WriteLine("a = " & a.ToString)
        Console.WriteLine("b = " & b.ToString)
        
        Console.WriteLine()
        Console.WriteLine("a + b = " & Complex.Add(a, b).ToString)
        Console.WriteLine("a - b = " & Complex.Subtract(a, b).ToString)
        Console.WriteLine("a * b = " & Complex.Multiply(a, b).ToString)
        Console.WriteLine("a / b = " & Complex.Divide(a, b).ToString)
        
        Console.WriteLine()
        Console.WriteLine("(double)a = " & Complex.ToDouble(a).ToString)
        Console.WriteLine("(Complex)5 = " & Complex.ToComplex(5).ToString)
    End Sub
End Class
using System;

// Value type definition for a complex number representation.
public struct Complex
{
    public double r, i;

    // Constructor.
    public Complex(double r, double i) { this.r = r; this.i = i; }

    // Returns one divided by the current value.
    public Complex Reciprocal
    {
        get
        {
            if (r == 0d && i == 0d)
                throw new DivideByZeroException();

            double div = r*r + i*i;
            return new Complex(r/div, -i/div);
        }
    }

    // Conversion operators.
    public static explicit operator double(Complex a)
    {
        return a.r;
    }
    public static implicit operator Complex(double r)
    {
        return new Complex(r,0d);
    }

    // Basic unary operators.
    public static Complex operator + (Complex a)
    {
        return a;
    }
    public static Complex operator - (Complex a)
    {
        return new Complex(-a.r, -a.i);
    }

    // Basic binary operators for addition, subtraction, multiplication, and division.
    public static Complex operator + (Complex a, Complex b)
    {
        return new Complex(a.r + b.r, a.i + b.i);
    }
    public static Complex operator - (Complex a, Complex b)
    {
        return new Complex(a.r - b.r, a.i - b.i);
    }
    public static Complex operator * (Complex a, Complex b)
    {
        return new Complex(a.r*b.r - a.i*b.i, a.r*b.i + a.i*b.r);
    }
    public static Complex operator / (Complex a, Complex b)
    {
        return a * b.Reciprocal;
    }

    // Override the ToString method so the value appears in write statements.
    public override string ToString() {
        return String.Format("({0}+{1}i)", r, i);
    }
}

// Entry point.
public class ValueTypeSample
{
    public static void Main()
    {
        Complex a = new Complex(0, 1);
        Complex b = new Complex(0, -2);

        Console.WriteLine();
        Console.WriteLine("a = " + a);
        Console.WriteLine("b = " + b);

        Console.WriteLine();
        Console.WriteLine("a + b = " + (a+b));
        Console.WriteLine("a - b = " + (a-b));
        Console.WriteLine("a * b = " + (a*b));
        Console.WriteLine("a / b = " + (a/b));

        Console.WriteLine();
        Console.WriteLine("(double)a = " + (double)a);
        Console.WriteLine("(Complex)5 = " + (Complex)5);
    }
}

La sortie de ce programme est présentée ci-dessous.

a = (0+1i)
b = (0+-2i)

a + b = (0+-1i)
a - b = (0+3i)
a * b = (2+0i)
a / b = (-0.5+0i)

(double)a = 0
(Complex)5 = (5+0i)

Voir aussi

Concepts

Vue d'ensemble de la bibliothèque de classes du .NET Framework

Introduction à la bibliothèque de classes .NET Framework dans Visual Studio

Énumérations dans le système de type commun

Référence

Object

ValueType

Autres ressources

Système de type commun