次の方法で共有


ref 構造体型 (C# リファレンス)

ref 修飾子は、構造体型の宣言内で使用できます。 ref struct 型のインスタンスはスタック上に割り当てられます。マネージド ヒープにエスケープすることはできません。 これを確実にするために、コンパイラでは次のように ref struct 型の使用が制限されます。

  • ref struct を配列の要素型にすることはできません。
  • ref struct をクラスまたは非 ref struct のフィールドの宣言型にすることはできません。
  • ref struct ではインターフェイスを実装できません。
  • ref structSystem.ValueType または System.Object にボックス化することはできません。
  • ref struct を型引数にすることはできません。
  • ref struct 変数をラムダ式またはローカル関数の中にキャプチャすることはできません。
  • C# 13 より前では、ref struct 変数は async メソッド内で使用できません。 C# 13 以降では、ref struct 変数は async メソッド内の await 式と同じブロック内で使用できません。 ただし、同期メソッドでは ref struct 変数を使用できます (Task または Task<TResult> を返すメソッドなど)。
  • C# 13 より前では、ref struct 変数は反復子の中で使用できません。 C# 13 以降では、ref struct 型と ref ローカルは、yield return ステートメントを含むコード セグメントの中にない場合は、反復子の中で使用できます。

破棄可能な 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 structreadonly として宣言するには、型宣言内で 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 structref フィールドを宣言できます。

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 フィールドに格納されている参照が、そのリファレントより長く存在しないことが保証されます。

ref フィールド機能を使用すると、System.Span<T> のような型を安全に実装できます。

public readonly ref struct Span<T>
{
    internal readonly ref T _reference;
    private readonly int _length;

    // Omitted for brevity...
}

Span<T> 型は、メモリ内の連続する要素にアクセスする参照を格納します。 参照を使用すると、Span<T> インスタンスは参照先のストレージのコピーを回避できます。

C# 言語仕様

詳細については、「C# 言語仕様」の次のセクションを参照してください。

ref フィールドの詳細については、「低レベル構造体の機能強化」の提案メモを参照してください。

関連項目