Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Verwenden Sie den ref Modifizierer beim Deklarieren eines Strukturtyps. Sie weisen Instanzen eines ref struct Typs im Stapel zu, und sie können dem verwalteten Heap nicht escapeen. Um diese Eigenschaft sicherzustellen, beschränkt der Compiler die Verwendung von ref struct Typen wie folgt:
- Sie können einen
ref structElementtyp eines Arrays nicht verwenden. - Sie können einen
ref structFeldtyp in einer Klasse oder nichtref structals Typ deklarieren. - Sie können kein Feld für
ref structSystem.ValueType oder System.Object. - Sie können keine
ref structVariable in einem Lambda-Ausdruck oder einer lokalen Funktion erfassen. - Vor C# 13 können Sie keine Variablen in einer
asyncMethode verwendenref struct. Ab C# 13 kann eineref struct-Variable nicht im selben Block wie derawait-Ausdruck in einerasync-Methode verwendet werden. Sie könnenref struct-Variablen jedoch in synchronen Methoden verwenden, z. B. in solchen, die Task oder Task<TResult> zurückgeben. - Vor C# 13 können Sie keine Variable in Iteratoren verwenden
ref struct. Ab C# 13 könnenref struct-Typen und lokaleref-Variablen in Iteratoren verwendet werden, vorausgesetzt, sie befinden sich nicht in Codesegmenten mit deryield return-Anweisung. - Vor C# 13 kann eine
ref structkeine Schnittstellen implementieren. Ab C# 13 kann eineref-Struktur Schnittstellen implementieren, muss jedoch den Regeln für die Verweissicherheit folgen. Beispielsweise kann einref struct-Typ nicht in den Schnittstellentyp konvertiert werden, da dies eine Boxing-Konvertierung erfordert. - Vor C# 13 kann eine
ref structkein Typargument sein. Ab C# 13 kann eineref structdas Typargument sein, wenn der Typparameter dieallows ref structin derwhere-Klausel angibt.
Die C#-Sprachreferenz dokumentiert die zuletzt veröffentlichte Version der C#-Sprache. Außerdem enthält sie erste Dokumentation für Features in der öffentlichen Vorschau für die kommende Sprachversion.
In der Dokumentation werden alle Features identifiziert, die in den letzten drei Versionen der Sprache oder in der aktuellen öffentlichen Vorschau eingeführt wurden.
Tipp
Informationen dazu, wann ein Feature erstmals in C# eingeführt wurde, finden Sie im Artikel zum Versionsverlauf der C#-Sprache.
In der Regel definieren Sie einen ref struct-Typ, wenn Sie einen Typ benötigen, der außerdem Datenmember von ref struct-Typen enthält:
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
Kombinieren Sie die ref struct- und readonly-Modifizierer in der Typdeklaration (der readonly-Modifizierer muss vor dem ref-Modifizierer stehen), um eine readonly als ref zu deklarieren:
public readonly ref struct ConversionRequest
{
public ConversionRequest(double rate, ReadOnlySpan<double> values)
{
Rate = rate;
Values = values;
}
public double Rate { get; }
public ReadOnlySpan<double> Values { get; }
}
In .NET sind ref struct und System.Span<T> Beispiele für eine System.ReadOnlySpan<T>.
ref-Felder
Sie können ein Feld in einem refref struct, wie das folgende Beispiel zeigt, deklarieren:
public ref struct RefFieldExample
{
private ref int number;
public int GetNumber()
{
if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref number))
{
throw new InvalidOperationException("The number ref field is not initialized.");
}
return number;
}
}
Ein ref-Feld kann den Wert null aufweisen. Verwenden Sie die Unsafe.IsNullRef<T>(T)-Methode, um zu bestimmen, ob ein ref-Feld null ist.
Sie können den readonly-Modifizierer wie folgt auf ein ref-Feld anwenden:
-
readonly ref: Sie können dieses Feld erneut zuweisen , indem Sie den= refOperator nur innerhalb eines Konstruktors oder einesinitAccessors verwenden. Sie können mit dem=-Operator an jedem beliebigen Punkt einen Wert zuweisen, der durch den Feldzugriffsmodifizierer zugelassen wird. -
ref readonly: An jedem Punkt können Sie diesem Feld keinen Wert mit dem=Operator zuweisen. Sie können das Feld jedoch mithilfe des= refOperators neu zuweisen. -
readonly ref readonly: Sie können dieses Feld nur in einem Konstruktor oder eineminitAccessor neu zuweisen. An keinem Punkt können Sie dem Feld einen Wert zuweisen.
Der Compiler stellt sicher, dass ein in einem ref-Feld gespeicherter Verweis nicht länger vorhanden ist als das Element, auf das er verweist.
Das Feldfeature ref ermöglicht eine sichere Implementierung von Typen wie System.Span<T>:
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;
// Omitted for brevity...
}
Der Span<T>-Typ speichert einen Verweis, über den er auf die zusammenhängenden Elemente im Arbeitsspeicher zugreift. Durch Die Verwendung eines Verweises verhindert eine Span<T> Instanz das Kopieren des speichers, auf den sie verweist.
Das verwerfbare Muster
Sie können eine verwerfbare ref structdefinieren. Stellen Sie dazu sicher, dass eine ref struct dem Dispose-Muster entspricht. Das heißt, es verfügt über eine Instanzmethode Dispose , die barrierefrei, parameterlos ist und einen void Rückgabetyp aufweist. Sie können die using-Anweisung oder -Deklaration mit einer Instanz einer verwerfbaren ref struct verwenden.
Ab C# 13 können Sie die IDisposable auch für ref struct-Typen implementieren. Die Überladungsauflösung bevorzugt jedoch das verwerfbare Muster gegenüber der Schnittstellenmethode. Der Compiler wird nur dann in eine IDisposable.Dispose Methode aufgelöst, wenn eine geeignete Dispose Methode nicht gefunden wird.
Einschränkungen für ref struct-Typen, die eine Schnittstelle implementieren
Diese Einschränkungen stellen sicher, dass ein ref struct Typ, der eine Schnittstelle implementiert, den erforderlichen Refsicherheitsregeln folgt.
- Sie können eine
ref structInstanz einer von ihr implementierten Schnittstelle nicht in eine Instanz konvertieren. Diese Einschränkung enthält die implizite Konvertierung, wenn Sie einenref structTyp als Argument verwenden und der Parameter ein Schnittstellentyp ist. Die Konvertierung führt zu einer Boxing-Konvertierung, die gegen die Verweissicherheit verstößt. Einref structkann Methoden als explizite Schnittstellendeklarationen deklarieren. Sie können jedoch nur über generische Methoden, bei denen die Typparametertypenallows ref structverwendet werden, auf diese Methoden zugreifen. - Eine
ref struct, die eine Schnittstelle implementiert, muss alle Instanz-Schnittstellenmember implementieren. Dieref structmuss Instanzmember implementieren, auch wenn die Schnittstelle eine Standardimplementierung enthält.
Der Compiler erzwingt diese Einschränkungen. Wenn Sie ref struct-Typen schreiben, die Schnittstellen implementieren, enthält jedes neue Update möglicherweise neue Standardschnittstellenmitglieder. Bis Sie eine Implementierung für neue Instanzmethoden bereitstellen, wird ihre Anwendung nicht kompiliert. Sie können keine bestimmte Implementierung für eine static Schnittstellenmethode mit einer Standardimplementierung bereitstellen.
Wichtig
Durch die Implementierung einer Schnittstelle mit einem ref struct Typ wird das Potenzial für spätere Änderungen beim Quellbruch und binären Unterbrechungen eingeführt. Der Umbruch tritt auf, wenn eine in einer ref struct anderen Assembly definierte Schnittstelle implementiert und diese Assembly ein Update bereitstellt, das dieser Schnittstelle Standardmember hinzufügt.
Der Quellumbruch erfolgt, wenn Sie das ref structelement neu kompilieren: Er muss das neue Element implementieren, obwohl es eine Standardimplementierung gibt.
Der binäre Umbruch erfolgt, wenn Sie die externe Assembly aktualisieren, ohne den ref struct Typ neu zu kompilieren , und der aktualisierte Code ruft die Standardimplementierung der neuen Methode auf. Die Runtime löst eine Ausnahme aus, wenn auf das Standardmitglied zugegriffen wird.
C#-Sprachspezifikation
Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation:
Weitere Informationen zu ref-Feldern finden Sie im Vorschlag zu Strukturverbesserungen auf niedriger Ebene.