ref
構造体型 (C# リファレンス)
ref
修飾子は、構造体型の宣言内で使用できます。 ref struct
型のインスタンスはスタック上に割り当てられます。マネージド ヒープにエスケープすることはできません。 これを確実にするために、コンパイラでは次のように ref struct
型の使用が制限されます。
ref struct
を配列の要素型にすることはできません。ref struct
をクラスまたは非ref struct
のフィールドの宣言型にすることはできません。ref struct
ではインターフェイスを実装できません。ref struct
を System.ValueType または System.Object にボックス化することはできません。ref struct
を型引数にすることはできません。ref struct
変数をラムダ式またはローカル関数でキャプチャすることはできません。ref struct
変数をasync
メソッド内で使用することはできません。 ただし、同期メソッドではref struct
変数を使用できます (Task または Task<TResult> を返すメソッドなど)。ref struct
変数を反復子内で使用することはできません。
破棄可能な ref struct
を定義できます。 そのためには、ref struct
が破棄可能なパターンに適合するようにします。 つまり、これには、アクセス可能かつパラメーターなしの、void
の戻り値型を持つ、インスタンス Dispose
メソッドが含まれます。 using ステートメントまたは宣言は、破棄可能な ref struct
のインスタンスと共に使用できます。
通常、ref struct
型のデータ メンバーも含む型が必要な場合は、ref struct
型を定義します。
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
ref struct
を readonly
として宣言するには、型宣言内で readonly
修飾子と ref
修飾子を組み合わせます (readonly
修飾子は ref
修飾子よりも前にある必要があります)。
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; }
}
.NET では、ref struct
の例として System.Span<T> と System.ReadOnlySpan<T> があります。
ref
フィールド
C# 11 以降では、次の例に示すように、ref struct
で ref
フィールドを宣言できます。
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;
}
}
ref
フィールドには、null
値を指定できます。 ref
フィールドが null
であるかどうかを判断するには、Unsafe.IsNullRef<T>(T) メソッドを使用します。
readonly
修飾子は、次の方法で ref
フィールドに適用できます。
readonly ref
: コンストラクターまたはinit
アクセサー内でのみ、このようなフィールドを= ref
演算子を使用して ref 再割り当てすることができます。 フィールド アクセス修飾子によって許可される任意の時点で、=
演算子を使用して値を割り当てることができます。ref readonly
: どの時点でも、このようなフィールドには、=
演算子を使用して値を割り当てることはできません。 ただし、= ref
演算子を使用してフィールドを ref 再割り当てすることはできます。readonly ref readonly
: このようなフィールドは、コンストラクターまたはinit
アクセサーでのみ ref 再割り当てできます。 どの時点でも、このフィールドに値を割り当てることはできません。
コンパイラでは、ref
フィールドに格納されている参照が、その参照先の値より長く存在しないようにします。 スコープ規則の詳細については、メソッド パラメーターに関する記事の「参照と値のスコープ」セクションを参照してください。
C# 言語仕様
詳細については、C# 言語仕様の「構造体」セクションを参照してください。
C# 7.2 以降で導入された機能の詳細については、次の機能の提案に関するメモを参照してください。