Tipi Ref<T> e ReadOnlyRef<T>

Classe Ref<T>

La Ref<T> classe è un tipo solo stack che archivia un riferimento a un valore di un tipo specificato. È semanticamente equivalente a un valore ref T, ma puoi usarlo come tipo di campo in un altro tipo struct solo per lo stack. Usarlo invece di ref T campi, che C# attualmente non supporta.

API della piattaforma:Ref<T>, ReadOnlyRef<T>

Come funziona

Annotazioni

A causa del modo in cui viene implementato in contratti .NET Standard diversi, presenta Ref<T> alcune piccole differenze in .NET Standard 1.4 e .NET Standard 2.1 (e runtime equivalenti di .NET Core). In particolare, in .NET Standard 1.4 può essere usato solo per fare riferimento ai campi all'interno di un oggetto, anziché valori arbitrari puntati da un riferimento gestito. Ciò è dovuto al fatto che le API sottostanti usate in .NET Standard 1.4 non dispongono del supporto predefinito per il Span<T> tipo.

Ref<T> in .NET Standard 1.4

Come indicato in precedenza, su .NET Standard 1.4, Ref<T> può puntare solo alle posizioni all'interno di un determinato object. Osservare il codice seguente:

// Be sure to include this using at the top of the file:
using Microsoft.Toolkit.HighPerformance;

// Define a sample model
class MyModel
{
    public int Number = 42;
}

var model = new MyModel();

// Create a Ref<T> pointing to the MyModel.Number field
Ref<int> byRef = new Ref<T>(model, ref model.Number);

// Modify the field indirectly
byRef.Value++;

Console.WriteLine(model.Number); // Prints 43!

Avviso

Il Ref<T> costruttore non convalida gli argomenti di input, il che significa che è responsabilità dell'utente passare un object valido e un riferimento a un campo all'interno di tale oggetto. In caso contrario, la Ref<T>.Value proprietà potrebbe restituire un riferimento non valido.

Ref<T> in .NET Standard 2.1

In .NET Standard 2.1 può Ref<T> puntare a qualsiasi ref T valore:

int number = 42;

// Create a Ref<int> pointing to 'number'
Ref<int> byRef1 = new Ref<int>(ref number);

// Modify 'number'
byRef1.Value++;

Console.WriteLine(number); // Prints 43!

Avviso

Questo tipo include alcune avvertenze e deve essere usato con attenzione, in quanto può causare arresti anomali di runtime se un'istanza Ref<T> viene creata con un riferimento non valido. In particolare, è consigliabile creare un'istanza Ref<T> che punta ai valori con una durata maggiore di quella dell'oggetto Ref<T> in uso. Si consideri il frammento di codice seguente:

public static ref int GetDummyReference()
{
    int number = 42;

    Ref<int> byRef = new Ref<T>(ref number);

    return ref byRef.Value;
}

Questa operazione verrà compilata ed eseguita correttamente, ma l'oggetto restituito ref int non sarà valido (cioè, non punterà a un percorso valido) e potrebbe causare un crash se dereferenziato. È responsabilità dell'utente tenere traccia della durata dei valori a cui si fa riferimento dai nuovi Ref<T> valori.

Annotazioni

Sebbene sia possibile creare un valore che avvolge un riferimento Ref<T>null, utilizzando l'espressione default(Ref<T>), il tipo Ref<T> non è progettato per essere usato con riferimenti annullabili e non include funzionalità appropriate per convalidare il riferimento interno. Se è necessario restituire un riferimento che può essere impostato su null, usare i NullableRef<T> tipi e NullableReadOnlyRef<T> .

Classe ReadOnlyRef<T>

La ReadOnlyRef<T> classe è un tipo stack-only che rispecchia Ref<T>, con l'eccezione che il suo costruttore accetta un parametro in T (un riferimento di sola lettura), anziché uno ref T. Analogamente, la proprietà Value ha un ref readonly T tipo restituito anziché ref T.

Examples

Altri esempi sono disponibili negli unit test.