Compartilhar via


Tipos de valores no CTS (Common Type System)

A maioria das linguagens de programação fornece tipos de dados internos, como números inteiros e números de ponto flutuante que são copiados quando eles são passados como argumentos (ou seja, eles são passados por valor).No .NET Framework, eles são chamados de tipos de valor.O tempo de execução oferece suporte a dois tipos de tipos de valor:

  • Tipos de valor interno

    O .NET Framework define tipos de valor internos, como System.Int32 e System.Boolean, que correspondem e são idênticos a tipos de dados primitivos usados por linguagens de programação.

  • Tipos de valor definidos pelo usuário

    Sua linguagem fornecerá maneiras para definir seus próprios tipos de valor, que derivam de System.ValueType ou System.Enum.Se você desejar definir um tipo que representa um valor que é pequeno, como um número complexo (usando dois números de ponto flutuante), você pode optar por defini-lo como um tipo de valor porque você pode passar a tipo de valor de forma eficiente por valor.Se o tipo que você está definindo seria passado com mais eficiência por referência, você deve defini-lo como uma classe em vez disso.

Para obter informações específicas para enumerações, consulte Enumerações no CTS (Common Type System).

Tipos de valor são armazenados de modo eficiente como tipos primitivos, mas ainda assim você pode chamar métodos neles, incluindo os métodos virtuais definidos nas classes System.Object e System.ValueType, bem como quaisquer métodos definidos no tipo de valor em si.Você pode criar instâncias dos tipos de valor, passá-las como parâmetros, armazená-las como variáveis locais ou armazená-las em um campo de outro objeto ou tipo de valor.Tipos de valor não tem a sobrecarga associada ao armazenamento de uma instância de uma classe e eles não exigem construtores.

Para cada tipo de valor, o tempo de execução fornece um tipo disponível comercialmente correspondente, que é uma classe que tem o mesmo estado e o mesmo comportamento que o tipo de valor.Alguns idiomas exigem que você use sintaxe especial quando o tipo disponível comercialmente é necessário; outros usam automaticamente o tipo disponível comercialmente quando ele é necessário.When you define a value type, you are defining both the boxed and the unboxed type.

Value types can have fields, properties, and events.They can also have static and nonstatic methods.When they are boxed, they inherit the virtual methods from System.ValueType, and they can implement zero or more interfaces.

Value types are sealed, which means that no other type can be derived from them.However, you can define virtual methods directly on the value type, and these methods can be called on either the boxed or unboxed form of the type.Although you cannot derive another type from a value type, you might define virtual methods on a value type when you are using a language in which it is more convenient to work with virtual methods than with nonvirtual or static methods.

The following example shows how to construct a value type for complex numbers.

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);
    }
}

A saída do programa é a seguinte.

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)

Consulte também

Conceitos

Visão geral sobre biblioteca classes do .NET Framework

Introdução ao Class Library do Visual Studio .NET Framework

Enumerações no CTS (Common Type System)

Referência

Object

ValueType

Outros recursos

Common Type System