Lazy<T> Klasse
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Bietet Unterstützung für die faule Initialisierung.
generic <typename T>
public ref class Lazy
public class Lazy<T>
[System.Runtime.InteropServices.ComVisible(false)]
[System.Serializable]
public class Lazy<T>
type Lazy<'T> = class
[<System.Runtime.InteropServices.ComVisible(false)>]
[<System.Serializable>]
type Lazy<'T> = class
Public Class Lazy(Of T)
Typparameter
- T
Der Typ des Objekts, das lazily initialisiert wird.
- Vererbung
-
Lazy<T>
- Abgeleitet
- Attribute
Beispiele
Im folgenden Beispiel wird die Verwendung der Lazy<T>-Klasse veranschaulicht, um eine faule Initialisierung mit Zugriff von mehreren Threads bereitzustellen.
Anmerkung
Im Beispiel wird der Lazy<T>(Func<T>)-Konstruktor verwendet. Außerdem wird die Verwendung des Lazy<T>(Func<T>, Boolean)-Konstruktors (angeben true
für isThreadSafe
) und des Lazy<T>(Func<T>, LazyThreadSafetyMode)-Konstruktors (angeben LazyThreadSafetyMode.ExecutionAndPublication für mode
) veranschaulicht. Wenn Sie zu einem anderen Konstruktor wechseln möchten, ändern Sie einfach, welche Konstruktoren auskommentiert sind.
Ein Beispiel, das das Zwischenspeichern von Ausnahmen mit denselben Konstruktoren veranschaulicht, finden Sie im Lazy<T>(Func<T>)-Konstruktor.
Im Beispiel wird eine LargeObject
Klasse definiert, die durch einen von mehreren Threads lazily initialisiert wird. Die vier wichtigen Codeabschnitte veranschaulichen die Erstellung des Initialisierers, der Factorymethode, der tatsächlichen Initialisierung und des Konstruktors der LargeObject
-Klasse, die beim Erstellen des Objekts eine Meldung anzeigt. Am Anfang der Main
-Methode erstellt das Beispiel den threadsicheren Lazy Initializer für LargeObject
:
lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);
// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line:
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject,
// LazyThreadSafetyMode.ExecutionAndPublication);
let lazyLargeObject = Lazy<LargeObject> initLargeObject
// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line:
// let lazyLargeObject = Lazy<LargeObject>(initLargeObject, true)
// let lazyLargeObject = Lazy<LargeObject>(initLargeObject,
// LazyThreadSafetyMode.ExecutionAndPublication)
lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject)
' The following lines show how to use other constructors to achieve exactly the
' same result as the previous line:
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, True)
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, _
' LazyThreadSafetyMode.ExecutionAndPublication)
Die Factorymethode zeigt die Erstellung des Objekts mit einem Platzhalter für die weitere Initialisierung:
static LargeObject InitLargeObject()
{
LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
// Perform additional initialization here.
return large;
}
let initLargeObject () =
let large = LargeObject Thread.CurrentThread.ManagedThreadId
// Perform additional initialization here.
large
Private Shared Function InitLargeObject() As LargeObject
Dim large As New LargeObject(Thread.CurrentThread.ManagedThreadId)
' Perform additional initialization here.
Return large
End Function
Beachten Sie, dass die ersten beiden Codeabschnitte mithilfe einer Lambda-Funktion kombiniert werden können, wie hier gezeigt:
lazyLargeObject = new Lazy<LargeObject>(() =>
{
LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
// Perform additional initialization here.
return large;
});
let lazyLargeObject = Lazy<LargeObject>(fun () ->
let large = LargeObject Thread.CurrentThread.ManagedThreadId
// Perform additional initialization here.
large)
lazyLargeObject = New Lazy(Of LargeObject)(Function ()
Dim large As New LargeObject(Thread.CurrentThread.ManagedThreadId)
' Perform additional initialization here.
Return large
End Function)
Das Beispiel hält an, um anzugeben, dass ein unbestimmter Zeitraum vor dem Auftreten der faulen Initialisierung verstrichen sein kann. Wenn Sie die EINGABETASTE Drücken, erstellt und startet das Beispiel drei Threads. Die ThreadProc
Methode, die von allen drei Threads verwendet wird, ruft die Value-Eigenschaft auf. Wenn dies zum ersten Mal geschieht, wird die LargeObject
Instanz erstellt:
LargeObject large = lazyLargeObject.Value;
// IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
// object after creation. You must lock the object before accessing it,
// unless the type is thread safe. (LargeObject is not thread safe.)
lock(large)
{
large.Data[0] = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("Initialized by thread {0}; last used by thread {1}.",
large.InitializedBy, large.Data[0]);
}
let large = lazyLargeObject.Value
// IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
// object after creation. You must lock the object before accessing it,
// unless the type is thread safe. (LargeObject is not thread safe.)
lock large (fun () ->
large.Data[0] <- Thread.CurrentThread.ManagedThreadId
printfn $"Initialized by thread {large.InitializedBy} last used by thread {large.Data[0]}.")
Dim large As LargeObject = lazyLargeObject.Value
' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
' object after creation. You must lock the object before accessing it,
' unless the type is thread safe. (LargeObject is not thread safe.)
SyncLock large
large.Data(0) = Thread.CurrentThread.ManagedThreadId
Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", _
large.InitializedBy, large.Data(0))
End SyncLock
Der Konstruktor der LargeObject
-Klasse, die den letzten Schlüsselabschnitt des Codes enthält, zeigt eine Meldung an und zeichnet die Identität des Initialisierungsthreads auf. Die Ausgabe des Programms wird am Ende der vollständigen Codeauflistung angezeigt.
int initBy = 0;
public LargeObject(int initializedBy)
{
initBy = initializedBy;
Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
}
type LargeObject(initBy) =
do
printfn $"LargeObject was created on thread id %i{initBy}."
Private initBy As Integer = 0
Public Sub New(ByVal initializedBy As Integer)
initBy = initializedBy
Console.WriteLine("LargeObject was created on thread id {0}.", initBy)
End Sub
Anmerkung
Aus Gründen der Einfachheit wird in diesem Beispiel eine globale Instanz von Lazy<T>verwendet, und alle Methoden sind static
(Shared
in Visual Basic). Dies sind keine Anforderungen für die Verwendung der faulen Initialisierung.
using System;
using System.Threading;
class Program
{
static Lazy<LargeObject> lazyLargeObject = null;
static LargeObject InitLargeObject()
{
LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
// Perform additional initialization here.
return large;
}
static void Main()
{
// The lazy initializer is created here. LargeObject is not created until the
// ThreadProc method executes.
lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);
// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line:
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject,
// LazyThreadSafetyMode.ExecutionAndPublication);
Console.WriteLine(
"\r\nLargeObject is not created until you access the Value property of the lazy" +
"\r\ninitializer. Press Enter to create LargeObject.");
Console.ReadLine();
// Create and start 3 threads, each of which uses LargeObject.
Thread[] threads = new Thread[3];
for (int i = 0; i < 3; i++)
{
threads[i] = new Thread(ThreadProc);
threads[i].Start();
}
// Wait for all 3 threads to finish.
foreach (Thread t in threads)
{
t.Join();
}
Console.WriteLine("\r\nPress Enter to end the program");
Console.ReadLine();
}
static void ThreadProc(object state)
{
LargeObject large = lazyLargeObject.Value;
// IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
// object after creation. You must lock the object before accessing it,
// unless the type is thread safe. (LargeObject is not thread safe.)
lock(large)
{
large.Data[0] = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("Initialized by thread {0}; last used by thread {1}.",
large.InitializedBy, large.Data[0]);
}
}
}
class LargeObject
{
public int InitializedBy { get { return initBy; } }
int initBy = 0;
public LargeObject(int initializedBy)
{
initBy = initializedBy;
Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
}
public long[] Data = new long[100000000];
}
/* This example produces output similar to the following:
LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject.
LargeObject was created on thread id 3.
Initialized by thread 3; last used by thread 3.
Initialized by thread 3; last used by thread 4.
Initialized by thread 3; last used by thread 5.
Press Enter to end the program
*/
open System
open System.Threading
type LargeObject(initBy) =
do
printfn $"LargeObject was created on thread id %i{initBy}."
member _.InitializedBy = initBy
member val Data = Array.zeroCreate<int64> 100000000
let initLargeObject () =
let large = LargeObject Thread.CurrentThread.ManagedThreadId
// Perform additional initialization here.
large
// The lazy initializer is created here. LargeObject is not created until the
// ThreadProc method executes.
let lazyLargeObject = Lazy<LargeObject> initLargeObject
// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line:
// let lazyLargeObject = Lazy<LargeObject>(initLargeObject, true)
// let lazyLargeObject = Lazy<LargeObject>(initLargeObject,
// LazyThreadSafetyMode.ExecutionAndPublication)
let threadProc (state: obj) =
let large = lazyLargeObject.Value
// IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
// object after creation. You must lock the object before accessing it,
// unless the type is thread safe. (LargeObject is not thread safe.)
lock large (fun () ->
large.Data[0] <- Thread.CurrentThread.ManagedThreadId
printfn $"Initialized by thread {large.InitializedBy} last used by thread {large.Data[0]}.")
printfn """
LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject."""
stdin.ReadLine() |> ignore
// Create and start 3 threads, each of which uses LargeObject.
let threads = Array.zeroCreate 3
for i = 0 to 2 do
threads[i] <- Thread(ParameterizedThreadStart threadProc)
threads[i].Start()
// Wait for all 3 threads to finish.
for t in threads do
t.Join()
printfn "\nPress Enter to end the program"
stdin.ReadLine() |> ignore
// This example produces output similar to the following:
// LargeObject is not created until you access the Value property of the lazy
// initializer. Press Enter to create LargeObject.
//
// LargeObject was created on thread id 3.
// Initialized by thread 3 last used by thread 3.
// Initialized by thread 3 last used by thread 4.
// Initialized by thread 3 last used by thread 5.
//
// Press Enter to end the program
Imports System.Threading
Friend Class Program
Private Shared lazyLargeObject As Lazy(Of LargeObject) = Nothing
Private Shared Function InitLargeObject() As LargeObject
Dim large As New LargeObject(Thread.CurrentThread.ManagedThreadId)
' Perform additional initialization here.
Return large
End Function
Shared Sub Main()
' The lazy initializer is created here. LargeObject is not created until the
' ThreadProc method executes.
lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject)
' The following lines show how to use other constructors to achieve exactly the
' same result as the previous line:
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, True)
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, _
' LazyThreadSafetyMode.ExecutionAndPublication)
Console.WriteLine(vbCrLf & _
"LargeObject is not created until you access the Value property of the lazy" _
& vbCrLf & "initializer. Press Enter to create LargeObject.")
Console.ReadLine()
' Create and start 3 threads, each of which uses LargeObject.
Dim threads(2) As Thread
For i As Integer = 0 To 2
threads(i) = New Thread(AddressOf ThreadProc)
threads(i).Start()
Next i
' Wait for all 3 threads to finish.
For Each t As Thread In threads
t.Join()
Next t
Console.WriteLine(vbCrLf & "Press Enter to end the program")
Console.ReadLine()
End Sub
Private Shared Sub ThreadProc(ByVal state As Object)
Dim large As LargeObject = lazyLargeObject.Value
' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
' object after creation. You must lock the object before accessing it,
' unless the type is thread safe. (LargeObject is not thread safe.)
SyncLock large
large.Data(0) = Thread.CurrentThread.ManagedThreadId
Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", _
large.InitializedBy, large.Data(0))
End SyncLock
End Sub
End Class
Friend Class LargeObject
Public ReadOnly Property InitializedBy() As Integer
Get
Return initBy
End Get
End Property
Private initBy As Integer = 0
Public Sub New(ByVal initializedBy As Integer)
initBy = initializedBy
Console.WriteLine("LargeObject was created on thread id {0}.", initBy)
End Sub
Public Data(99999999) As Long
End Class
' This example produces output similar to the following:
'
'LargeObject is not created until you access the Value property of the lazy
'initializer. Press Enter to create LargeObject.
'
'LargeObject was created on thread id 3.
'Initialized by thread 3; last used by thread 3.
'Initialized by thread 3; last used by thread 5.
'Initialized by thread 3; last used by thread 4.
'
'Press Enter to end the program
'
Hinweise
Verwenden Sie faule Initialisierung, um die Erstellung eines großen oder ressourcenintensiven Objekts oder die Ausführung eines ressourcenintensiven Vorgangs zu verzögern, insbesondere, wenn eine solche Erstellung oder Ausführung während der Lebensdauer des Programms nicht auftritt.
Um sich auf die faule Initialisierung vorzubereiten, erstellen Sie eine Instanz von Lazy<T>. Das Typargument des Lazy<T> Objekts, das Sie erstellen, gibt den Typ des Objekts an, das Sie lazily initialisieren möchten. Der Konstruktor, den Sie zum Erstellen des Lazy<T>-Objekts verwenden, bestimmt die Merkmale der Initialisierung. Lazy initialization occurs the first time the Lazy<T>.Value property is accessed.
In den meisten Fällen hängt die Auswahl eines Konstruktors von Ihren Antworten auf zwei Fragen ab:
Wird auf das lazily initialisierte Objekt von mehr als einem Thread zugegriffen? Wenn dies der Fall ist, erstellt das Lazy<T>-Objekt es möglicherweise in einem beliebigen Thread. Sie können einen der einfachen Konstruktoren verwenden, deren Standardverhalten darin besteht, ein threadsicheres Lazy<T>-Objekt zu erstellen, sodass nur eine Instanz des lazily instanziierten Objekts erstellt wird, unabhängig davon, wie viele Threads versuchen, darauf zuzugreifen. Zum Erstellen eines Lazy<T> Objekts, das nicht threadsicher ist, müssen Sie einen Konstruktor verwenden, mit dem Sie keine Threadsicherheit angeben können.
Vorsicht
Durch das Schützen des Lazy<T> Objektthreads wird das lazily initialisierte Objekt nicht geschützt. Wenn mehrere Threads auf das lazily initialisierte Objekt zugreifen können, müssen Sie dessen Eigenschaften und Methoden für den Multithreadzugriff sicher machen.
Erfordert die faule Initialisierung viel Code, oder verfügt das lazily initialisierte Objekt über einen parameterlosen Konstruktor, der alles benötigt und keine Ausnahmen auslöst? Wenn Sie Initialisierungscode schreiben oder Ausnahmen behandeln müssen, verwenden Sie einen der Konstruktoren, die eine Factorymethode verwenden. Schreiben Sie den Initialisierungscode in der Factorymethode.
In der folgenden Tabelle ist dargestellt, welcher Konstruktor basierend auf diesen beiden Faktoren ausgewählt werden soll:
Der Zugriff auf das Objekt erfolgt über | Wenn kein Initialisierungscode erforderlich ist (parameterloser Konstruktor), verwenden Sie | Wenn Initialisierungscode erforderlich ist, verwenden Sie |
---|---|---|
Mehrere Threads | Lazy<T>() | Lazy<T>(Func<T>) |
Ein Thread |
Lazy<T>(Boolean) mit isThreadSafe auf false festgelegt. |
Lazy<T>(Func<T>, Boolean) mit isThreadSafe auf false festgelegt. |
Sie können einen Lambda-Ausdruck verwenden, um die Factorymethode anzugeben. Dadurch bleibt der gesamte Initialisierungscode an einer zentralen Stelle. Der Lambda-Ausdruck erfasst den Kontext, einschließlich aller Argumente, die Sie an den Konstruktor des lazily initialisierten Objekts übergeben.
Ausnahmezwischenspeicherung Wenn Sie Factorymethoden verwenden, werden Ausnahmen zwischengespeichert. Wenn die Factorymethode eine Ausnahme auslöst, wenn ein Thread zum ersten Mal versucht, auf die Value-Eigenschaft des Lazy<T> Objekts zuzugreifen, wird bei jedem nachfolgenden Versuch dieselbe Ausnahme ausgelöst. Dadurch wird sichergestellt, dass jeder Aufruf der Value-Eigenschaft dasselbe Ergebnis erzeugt und subtile Fehler vermeidet, die auftreten können, wenn unterschiedliche Threads unterschiedliche Ergebnisse erhalten. Die Lazy<T> steht für eine tatsächliche T
, die sonst zu einem früheren Zeitpunkt initialisiert worden wäre, normalerweise während des Starts. Ein Fehler zu diesem früheren Zeitpunkt ist in der Regel tödlich. Wenn es ein Potenzial für einen wiederherstellbaren Fehler gibt, empfiehlt es sich, die Wiederholungslogik in die Initialisierungsroutine zu erstellen (in diesem Fall die Factorymethode), genau wie sie dies wäre, wenn Sie keine faule Initialisierung verwenden würden.
Alternative zum Sperren In bestimmten Situationen sollten Sie den Aufwand des Standardsperrverhaltens des Lazy<T> Objekts vermeiden. In seltenen Situationen kann es ein Potenzial für Deadlocks geben. In solchen Fällen können Sie den Lazy<T>(LazyThreadSafetyMode)- oder Lazy<T>(Func<T>, LazyThreadSafetyMode)-Konstruktor verwenden und LazyThreadSafetyMode.PublicationOnlyangeben. Dadurch kann das Lazy<T>-Objekt eine Kopie des lazily initialisierten Objekts in jedem der verschiedenen Threads erstellen, wenn die Threads die Value Eigenschaft gleichzeitig aufrufen. Das Lazy<T>-Objekt stellt sicher, dass alle Threads dieselbe Instanz des lazily initialisierten Objekts verwenden und die nicht verwendeten Instanzen verwerfen. Die Kosten für die Reduzierung des Sperraufwands sind daher, dass Ihr Programm manchmal zusätzliche Kopien eines teuren Objekts erstellen und verwerfen kann. In den meisten Fällen ist dies unwahrscheinlich. Die Beispiele für die Konstruktoren Lazy<T>(LazyThreadSafetyMode) und Lazy<T>(Func<T>, LazyThreadSafetyMode) veranschaulichen dieses Verhalten.
Wichtig
Wenn Sie LazyThreadSafetyMode.PublicationOnlyangeben, werden Ausnahmen niemals zwischengespeichert, auch wenn Sie eine Factorymethode angeben.
Äquivalente Konstruktoren Zusätzlich zur Aktivierung der Verwendung von LazyThreadSafetyMode.PublicationOnlykönnen die Lazy<T>(LazyThreadSafetyMode) und Lazy<T>(Func<T>, LazyThreadSafetyMode) Konstruktoren die Funktionalität der anderen Konstruktoren duplizieren. In der folgenden Tabelle sind die Parameterwerte aufgeführt, die ein entsprechendes Verhalten erzeugen.
So erstellen Sie ein Lazy<T>-Objekt, das | Legen Sie für Konstruktoren mit einem LazyThreadSafetyMode mode -Parameter mode auf |
Legen Sie für Konstruktoren mit einem booleschen isThreadSafe -Parameter isThreadSafe auf |
Für Konstruktoren ohne Threadsicherheitsparameter |
---|---|---|---|
Vollständig threadsicher; verwendet sperren, um sicherzustellen, dass nur ein Thread den Wert initialisiert. | ExecutionAndPublication | true |
Alle diese Konstruktoren sind vollständig threadsicher. |
Nicht threadsicher. | None | false |
Nicht zutreffend. |
Vollständig threadsicher; Threads laufen, um den Wert zu initialisieren. | PublicationOnly | Nicht zutreffend. | Nicht zutreffend. |
Weitere Funktionen Weitere Informationen zur Verwendung von Lazy<T> mit threadstatischem Feld oder als Sicherungsspeicher für Eigenschaften finden Sie unter Lazy Initialization.
Konstruktoren
Lazy<T>() |
Initialisiert eine neue Instanz der Lazy<T> Klasse. Wenn eine faule Initialisierung auftritt, wird der parameterlose Konstruktor des Zieltyps verwendet. |
Lazy<T>(Boolean) |
Initialisiert eine neue Instanz der Lazy<T> Klasse. Wenn die faule Initialisierung auftritt, werden der parameterlose Konstruktor des Zieltyps und der angegebene Initialisierungsmodus verwendet. |
Lazy<T>(Func<T>) |
Initialisiert eine neue Instanz der Lazy<T> Klasse. Wenn eine faule Initialisierung auftritt, wird die angegebene Initialisierungsfunktion verwendet. |
Lazy<T>(Func<T>, Boolean) |
Initialisiert eine neue Instanz der Lazy<T> Klasse. Wenn eine faule Initialisierung auftritt, werden die angegebene Initialisierungsfunktion und der Initialisierungsmodus verwendet. |
Lazy<T>(Func<T>, LazyThreadSafetyMode) |
Initialisiert eine neue Instanz der Lazy<T> Klasse, die die angegebene Initialisierungsfunktion und den Threadsicherheitsmodus verwendet. |
Lazy<T>(LazyThreadSafetyMode) |
Initialisiert eine neue Instanz der Lazy<T> Klasse, die den parameterlosen Konstruktor von |
Lazy<T>(T) |
Initialisiert eine neue Instanz der Lazy<T> Klasse, die einen präinitialisierten angegebenen Wert verwendet. |
Eigenschaften
IsValueCreated |
Ruft einen Wert ab, der angibt, ob für diese Lazy<T> Instanz ein Wert erstellt wurde. |
Value |
Ruft den lazily initialisierten Wert der aktuellen Lazy<T> Instanz ab. |
Methoden
Equals(Object) |
Bestimmt, ob das angegebene Objekt dem aktuellen Objekt entspricht. (Geerbt von Object) |
GetHashCode() |
Dient als Standardhashfunktion. (Geerbt von Object) |
GetType() |
Ruft die Type der aktuellen Instanz ab. (Geerbt von Object) |
MemberwiseClone() |
Erstellt eine flache Kopie der aktuellen Object. (Geerbt von Object) |
ToString() |
Erstellt und gibt eine Zeichenfolgendarstellung der Value -Eigenschaft für diese Instanz zurück. |
Gilt für:
Threadsicherheit
Standardmäßig sind alle öffentlichen und geschützten Member der Lazy<T>-Klasse threadsicher und können gleichzeitig aus mehreren Threads verwendet werden. Diese Threadsicherheitsgarantien können optional und pro Instanz mithilfe von Parametern für die Konstruktoren des Typs entfernt werden.