(0) exportieren Drucken
Alle erweitern

Werttypen im allgemeinen Typsystem

Aktualisiert: November 2007

Die meisten Programmiersprachen bieten integrierte Datentypen, wie ganze Zahlen und Gleitkommazahlen, die bei ihrer Übergabe als Argumente kopiert werden (d. h., sie werden als Wert übergeben). In .NET Framework werden diese Typen als Werttypen bezeichnet. Die Laufzeit unterstützt zwei Arten von Werttypen:

  • Integrierte Werttypen

    In .NET Framework werden integrierte Werttypen definiert, z. B. System.Int32 und System.Boolean. Diese entsprechen den von Programmiersprachen verwendeten primitiven Datentypen und sind mit ihnen identisch.

  • Benutzerdefinierte Werttypen

    Ihre Programmiersprache bietet Möglichkeiten, eigene Werttypen zu definieren, die von System.ValueType oder System.Enum abgeleitet werden. Wenn Sie einen Typ zur Darstellung eines kleinen Werts definieren möchten, z. B. einer komplexen Zahl (in der zwei Gleitkommazahlen verwendet werden), können Sie den Typ beispielsweise als Werttyp definieren, da er effizient als Wert übergeben werden kann. Falls der definierte Typ effizienter als Verweis übergeben werden könnte, sollten Sie ihn stattdessen als Klasse definieren.

Spezifische Informationen über Enumerationen finden Sie unter Enumerationen im allgemeinen Typsystem.

Werttypen werden genauso effektiv wie primitive Typen gespeichert. Für Werttypen können jedoch darüber hinaus Methoden aufgerufen werden, darunter die in der System.Object-Klasse und der System.ValueType-Klasse definierten virtuellen Methoden sowie alle für den Werttyp selbst definierten Methoden. Sie können Instanzen von Werttypen erstellen, diese als Parameter übergeben, als lokale Variablen speichern oder im Feld eines anderen Werttyps oder Objekts speichern. Ihre Verarbeitung ist weniger aufwendig, da keine Instanz einer Klasse gespeichert werden muss und sie keine Konstruktoren erfordern.

Die Common Language Runtime stellt für jeden Werttyp einen entsprechenden geschachtelten Werttyp bereit, der eine Klasse darstellt, die denselben Zustand und dasselbe Verhalten wie der Werttyp aufweist. In einigen Sprachen muss eine spezielle Syntax verwendet werden, wenn ein mittels Boxing gepackter Typ erforderlich ist; in anderen Sprachen wird der mittels Boxing gepackte Typ bei Bedarf automatisch verwendet. Die Definition eines Werttyps schließt sowohl den mittels Boxing gepackten als auch den mittels Unboxing entpackten Typ ein.

Werttypen können über Felder, Eigenschaften und Ereignisse sowie über statische und nicht statische Methoden verfügen. Mittels Boxing gepackte Werttypen erben virtuelle Methoden von System.ValueType und können keine oder mehrere Schnittstellen implementieren.

Werttypen sind versiegelt, was bedeutet, dass kein anderer Typ von ihnen abgeleitet werden kann. Sie können virtuelle Methoden jedoch direkt für den Werttyp definieren, und diese Methoden können entweder für die mittels Boxing gepackte oder die mittels Unboxing entpackte Form des Typs aufgerufen werden. Obwohl die Ableitung eines anderen Typs von einem Werttyp nicht möglich ist, können Sie bei Verwendung einer Sprache, in der virtuelle Methoden die bequemere Alternative zu nicht virtuellen oder statischen Methoden darstellen, virtuelle Methoden für einen Werttyp definieren.

Das folgende Beispiel veranschaulicht, wie Sie einen Werttyp für komplexe Zahlen erstellen.

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

Dieses Programm gibt folgendes Ergebnis aus:

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)

Community-Beiträge

HINZUFÜGEN
Anzeigen:
© 2014 Microsoft