次の方法で共有


参照パラメーター、変数、戻り値に関連付けられているエラーと警告

次のエラーは、参照変数を使用しているときに生成されることがあります。

  • CS0192: readonly フィールドは ref 値としても out 値としても使用できません (コンストラクターでは可)
  • CS0199: static readonly フィールドは ref 値としても out 値としても使用できません (静的コンストラクターでは可)
  • CS0206: 参照を返さないプロパティまたはインデクサーは out 値としても ref 値としても使用できません
  • CS0631: refout はこのコンテキストでは無効です
  • CS0767: refout についてのみ相違があるオーバーロードがメソッドに含まれるようになるため、指定した型パラメーターを持つインターフェイスを継承できません
  • CS1510: ref または out 値は、割り当て可能な変数でなければなりません
  • CS1605: 変数は読み取り専用であるため、ref 値としても out 値としても使用できません
  • CS1623: 反復子には refinout のどのパラメーターも指定できません
  • CS1649: readonly フィールドのメンバーは ref 値としても out 値としても使用できません (コンストラクターでは可)
  • CS1651: 静的な読み取り専用フィールドのフィールドは ref 値としても out 値としても使用できません (静的コンストラクターでは可)
  • CS1655: 型のフィールドは ref 値としても out 値としても使用できません
  • CS1657: 変数は ref 値としても out 値としても使用できません
  • CS1741: refout のどちらのパラメーターにも既定値を指定できません
  • CS1939: 範囲変数は out パラメーターとしても ref パラメーターとしても渡すことはできません
  • CS1988: 非同期メソッドには refinout のどのパラメーターも指定できません
  • CS7084: Windows ランタイム イベントは out パラメーターとしても ref パラメーターとしても渡すことはできません。
  • CS8166: ref パラメーターではないため、そのパラメーターを参照渡しで返すことができません
  • CS8167: ref パラメーターでも out パラメーターでもないため、そのパラメーターのメンバーを参照渡しで返すことができません
  • CS8168: ref ローカルではないため、そのローカルを参照渡しで返すことができません
  • CS8169: ref ローカルではないため、そのローカル変数のメンバーを参照渡しで返すことができません
  • CS8196: 暗黙的に型指定された out 変数への参照は、同じ引数リストでは使用できません。
  • CS8325: "await" は、ref 条件付きの演算子を含む式では使用できません
  • CS8326: 条件付きの演算子の両辺の値は、両方とも ref 値にする必要があるか、どちらも ref 値であってはなりません
  • CS8327: 式は、代替 ref 値と一致させるために正しい型である必要があります
  • CS8329: 変数は読み取り専用変数であるため、ref 値としても out 値としても使用できません
  • CS8330: 変数のメンバーは読み取り専用変数であるため、ref 値としても out 値としても使用できません
  • CS8331: 変数は読み取り専用変数であるため、変数に代入できません。また、ref 代入の右辺として使用することもできません
  • CS8332: 変数は読み取り専用変数であるため、変数のメンバーに代入できません。また、ref 代入の右辺として使用することもできません
  • CS8337: "ref" 拡張メソッドの最初のパラメーターは、値の型または構造体に制限されたジェネリック型である必要があります。
  • CS8338: 拡張メソッドの最初の "in" または "ref readonly" パラメーターは、具象 (非ジェネリック) 値の型である必要があります。
  • CS8351: ref 条件付きの演算子のブランチでは、互換性のない宣言スコープを持つ変数を参照できません
  • CS8373: ref 代入の左辺は ref 変数である必要があります。
  • CS8374: ref 代入できません。ソースのエスケープ スコープが宛先よりも狭くなっています。
  • CS8388: out 変数を ref ローカルとして宣言できません
  • CS8977: "UnmanagedCallersOnly" 属性が設定されたメソッドのシグネチャでは、"ref"、"in"、"out" のどれも使用できません。
  • CS9072: 分解変数を ref ローカルとして宣言できません
  • CS9077: ref パラメーターを介してパラメーターを参照渡しで返すことができません。それは return ステートメントでのみ返すことができます
  • CS9078: ref パラメーターを介してパラメーターのメンバーを参照渡しで返すことができません。それは return ステートメントでのみ返すことができます
  • CS9079: ソースは return ステートメントを介してのみ現在のメソッドをエスケープできるため、ref 代入できません。
  • CS9096: 宛先よりも広い値のエスケープ スコープがソースにあり、宛先よりも狭いエスケープ スコープを持つ値のソースを介して代入が可能であるため、ref 代入できません。
  • CS9101: UnscopedRefAttribute は構造体または仮想インターフェイスのインスタンスのメソッドとプロパティにのみ適用でき、コンストラクターまたは初期化専用メンバーには適用できません。
  • CS9102: 実装されるメンバーにこの属性がないため、インターフェイスの実装には UnscopedRefAttribute を適用できません。
  • CS9104: 型の using ステートメント リソースは、非同期メソッドでも非同期ラムダ式でも使用できません。
  • CS9190: readonly 修飾子は ref の後に指定する必要があります。
  • CS9199: ref readonly パラメーターに Out 属性を指定することはできません。

参照変数が正しく使用されていない場合は、次の警告が生成されます。

  • CS9085: これは変数を ref 代入しますが、宛先のエスケープ スコープはソースよりも狭くなっています。
  • CS9086: ref 条件付きの演算子のブランチでは、互換性のない宣言スコープを持つ変数を参照します
  • CS9087: これはパラメーターを参照返しで返しますが、ref パラメーターではありません
  • CS9089: これは、ref パラメーターでも out パラメーターでもないパラメーターのメンバーを参照渡しで返します
  • CS9091: これはローカルを参照渡しで返しますが、ref ローカルではありません
  • CS9092: これはローカルのメンバーを参照渡しで返しますが、ref ローカルではありません
  • CS9093: これは ref 代入しますが、ソースは return ステートメントを介してのみ現在のメソッドをエスケープできます。
  • CS9094: これは ref パラメーターを介してパラメーターを参照渡しで返しますが、それは return ステートメントでのみ安全に返すことができます
  • CS9095: これは、ref パラメーターを介してパラメーターのメンバーを参照渡しで返しますが、それは return ステートメントでのみ安全に返すことができます
  • CS9097: これは ref 代入しますが、宛先よりも広い値のスケープ スコープがソースにあり、ソースよりも狭いエスケープ スコープを持つ値の宛先を介して代入することができます。
  • CS9191: in パラメーターに対応する引数の ref 修飾子は in と同じです。代わりに in を使用することを検討してください。
  • CS9192: 引数は ref または in キーワードと共に渡す必要があります。
  • CS9193: 引数は ref readonly パラメーターに渡されるため変数にする必要があります
  • CS9195: 引数は in キーワードと共に渡す必要があります
  • CS9196: パラメーターの参照種別修飾子が、オーバーライドまたは実装されたメンバーの対応するパラメーターと一致しません。
  • CS9197: パラメーターの参照種別修飾子が、非表示のメンバーの対応するパラメーターと一致しません。
  • CS9198: パラメーターの参照種別修飾子が、ターゲットの対応するパラメーターと一致しません。
  • CS9200: ref readonly パラメーターに既定値が指定されていますが、ref readonly は参照にのみ使用する必要があります。そのパラメーターは in として宣言することを検討してください。
  • CS9201: 使用前に Ref フィールドに ref 代入する必要があります。
  • CS9265: Field は参照割り当てされておらず、常に既定値 (null 参照) を持つことになります

これらのエラーと警告は、次のテーマに従います。

この記事では、"参照変数" という用語が、inref readonlyrefout 修飾子のいずれか、ref ローカル変数、ref structref フィールド、または ref 戻り値で宣言されたパラメーターの一般的な用語として使用されます。 参照変数は、"参照先" と呼ばれる別の変数を参照します。

構文は正しくありません

これらのエラーは、参照変数に関して正しくない構文を使用していることを示します。

  • CS8373: ref 代入の左辺は ref 変数である必要があります。
  • CS8388: out 変数を ref ローカルとして宣言できません。
  • CS9190: readonly 修飾子は ref の後に指定する必要があります。

次のいずれかの変更でエラーを修正できます。

  • = ref 演算子の左オペランドは参照変数である必要があります。 正しい構文の詳細については、「参照変数」を参照してください。
  • パラメーター修飾子 ref readonly は、その順序である必要があります。 readonly ref は有効なパラメーター修飾子ではありません。 単語の順序を切り替えてください。
  • ローカル変数を out として宣言することはできません。 ローカル参照変数を宣言するには、ref を使用します。

参照変数の制限

次のエラーは、参照変数が存在する場合は参照変数を使用できないことを示しています。

  • CS0631: refout はこのコンテキストでは無効です
  • CS0767: refout についてのみ相違があるオーバーロードがメソッドに含まれるようになるため、指定した型パラメーターを持つインターフェイスを継承できません
  • CS1623: 反復子には refinout のどのパラメーターも指定できません
  • CS1741: refout のどちらのパラメーターにも既定値を指定できません
  • CS1939: 範囲変数は out パラメーターとしても ref パラメーターとしても渡すことはできません
  • CS1988: 非同期メソッドには refinout のどのパラメーターも指定できません
  • CS7084: Windows ランタイム イベントは out パラメーターとしても ref パラメーターとしても渡すことはできません。
  • CS8196: 暗黙的に型指定された out 変数への参照は、同じ引数リストでは使用できません。
  • CS8325: "await" は、ref 条件付きの演算子を含む式では使用できません
  • CS8326: 条件付きの演算子の両辺の値は、両方とも ref 値にする必要があるか、どちらも ref 値であってはなりません
  • CS8327: 式は、代替 ref 値と一致させるために正しい型である必要があります
  • CS8337: "ref" 拡張メソッドの最初のパラメーターは、値の型または構造体に制限されたジェネリック型である必要があります。
  • CS8338: 拡張メソッドの最初の "in" または "ref readonly" パラメーターは、具象 (非ジェネリック) 値の型である必要があります。
  • CS8977: "UnmanagedCallersOnly" 属性が設定されたメソッドのシグネチャでは、"ref"、"in"、"out" のどれも使用できません。
  • CS9072: 分解変数を ref ローカルとして宣言できません
  • CS9104: 型の using ステートメント リソースは、非同期メソッドでも非同期ラムダ式でも使用できません。
  • CS9199: ref readonly パラメーターに Out 属性を指定することはできません。

次の警告は、参照変数を使用すべきではないこと、また、安全でない可能性があることを示しています。

  • CS9196: パラメーターの参照種別修飾子が、オーバーライドまたは実装されたメンバーの対応するパラメーターと一致しません。
  • CS9197: パラメーターの参照種別修飾子が、非表示のメンバーの対応するパラメーターと一致しません。
  • CS9198: パラメーターの参照種別修飾子が、ターゲットの対応するパラメーターと一致しません。
  • CS9200: ref readonly パラメーターに既定値が指定されていますが、ref readonly は参照にのみ使用する必要があります。そのパラメーターは in として宣言することを検討してください。
  • CS9201: 使用前に Ref フィールドに ref 代入する必要があります。
  • CS9265: Field は参照割り当てされておらず、常に既定値 (null 参照) を持つことになります

エラーを修正するには、参照変数が許可されていない場合は、それを削除します。

  • インデクサー反復子、および非同期メソッドから、inref、および out パラメーターを削除します。
  • await を含む ? :ref 条件式 () を削除します。
  • 型が値の型でない、または値の型として制約されているジェネリック型でない場合、拡張メソッドの最初のパラメーターから ref 修飾子を削除します。
  • [条件付きの演算子式] の両方が ref 変数である必要があります。あるいは、どちらもその変数であってはなりません。 いずれかの式から ref を削除するか、もう一方の式にそれを追加します。 ref 条件式の場合、両方の式が同じ型である必要があります。
  • refout の両方のパラメーターには既定値を指定できません。 ref または out のいずれかの修飾子を削除するか、既定値を削除します。
  • 暗黙的に型指定された out 変数宣言は、同じ引数リスト内の他の場所にも表示できません。
  • async メソッドのラムダ式の using ステートメントには参照変数を配置できません。
  • LINQ クエリ式の範囲変数を参照渡しすることはできません。
  • オブジェクトを参照変数に分解することはできません。 参照変数を値変数に置き換えてください。
  • メソッドのオーバーロードで refout についてのみ相違がある場合、複数のインターフェイスを実装することはできません。 たとえば、あるインターフェイスで void M(ref int i) が宣言され、別のインターフェイスで void M(out int i) が宣言されています。 クラスでは、そのインターフェイスの両方は実装できません。これはメソッドを区別することができないためです。 実装できるのはそのインターフェイスのどちらかのみです。
  • System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute 属性が指定されたメソッドでは、参照パラメーターを使用できません。
  • Windows ランタイム イベントを参照変数として渡すことはできません。
  • リモート API では、ref readonly パラメーターに System.Runtime.InteropServices.OutAttribute を適用することはできません。
  • コンストラクターの ref フィールドを初期化するか、フィールド初期化子として初期化します。

unscoped ref 制約

ref パラメーターの unscoped 修飾子は、一部の場所では許可されていません。

  • CS9101: UnscopedRefAttribute は構造体インスタンスまたは仮想インターフェイスのメソッドとプロパティにのみ適用でき、コンストラクターまたは初期化専用メンバーには適用できません。
  • CS9102: 実装されるメンバーにこの属性がないため、インターフェイスの実装には UnscopedRefAttribute を適用できません。

エラーの原因となったパラメーター宣言の unscoped 修飾子を削除する必要があります。

参照変数には参照先が必要

参照パラメーター、参照戻り値、ref ローカル代入のいずれかの引数として変数を指定する必要があります。

  • CS0206: 参照を返さないプロパティまたはインデクサーは out 値としても ref 値としても使用できません
  • CS1510: ref または out 値は、割り当て可能な変数でなければなりません

警告:

  • CS9191: in パラメーターに対応する引数の ref 修飾子は in と同じです。代わりに in を使用することを検討してください。
  • CS9192: 引数は ref または in キーワードと共に渡す必要があります。
  • CS9193: 引数は ref readonly パラメーターに渡されるため変数にする必要があります
  • CS9195: 引数は in キーワードと共に渡す必要があります

変数を使用する必要がある場合に、値が計算される式を使用すると、コンパイラによってこれらのエラーが生成されます。 これを使用するには、その式の結果を変数に格納する必要があります。 たとえば、プロパティとインデクサーは変数ではなく値を返します。 結果を変数に格納し、その変数への参照を渡す必要があります。

書き込み可能な参照変数には書き込み可能な参照先が必要

書き込み可能な参照変数では、参照先も書き込み可能である必要があります。 次のエラーは、変数が書き込み可能ではないことを示しています。

  • CS0192: readonly フィールドは ref 値としても out 値としても使用できません (コンストラクターでは可)
  • CS0199: static readonly フィールドは ref 値としても out 値としても使用できません (静的コンストラクターでは可)
  • CS1605: 変数は読み取り専用であるため、ref 値としても out 値としても使用できません
  • CS1649: readonly フィールドのメンバーは ref 値としても out 値としても使用できません (コンストラクターでは可)
  • CS1651: static readonly フィールドのフィールドを ref または out 値として使用できません (静的コンストラクターでは可)
  • CS1655: 型のフィールドは ref 値としても out 値としても使用できません
  • CS1657: 変数は ref 値としても out 値としても使用できません
  • CS8329: 変数は読み取り専用変数であるため、ref 値としても out 値としても使用できません
  • CS8330: 変数のメンバーは読み取り専用変数であるため、ref 値としても out 値としても使用できません
  • CS8331: 変数は読み取り専用変数であるため、変数に代入できません。また、ref 代入の右辺として使用することもできません
  • CS8332: 変数は読み取り専用変数であるため、変数のメンバーに代入できません。また、ref 代入の右辺として使用することもできません

書き込み可能でない変数の例を次に示します。

  • 読み取り専用フィールド (インスタンス フィールドと静的フィールドの両方)。
  • readonly フィールドのメンバー。
  • this 変数。
  • foreach 繰り返し変数
  • using 変数または fixed 変数。

値をコピーし、そのコピーへの参照を渡す必要があります。

Ref 安全性の違反

コンパイラでは、参照先と参照変数の safe context が追跡されます。 無効になった参照先変数を参照変数が参照していると、エラー、またはアンセーフ コードの警告がコンパイラによって発行されます。 参照先には、少なくとも参照変数の ref safe context と同じ幅の safe context が必要です。 これらの安全性チェックに違反するということは、参照変数が参照先変数ではなくランダム メモリにアクセスするということです。

  • CS8166: ref パラメーターではないため、そのパラメーターを参照渡しで返すことができません
  • CS8167: ref パラメーターでも out パラメーターでもないため、そのパラメーターのメンバーを参照渡しで返すことができません
  • CS8168: ref ローカルではないため、そのローカルを参照渡しで返すことができません
  • CS8169: ref ローカルではないため、そのローカル変数のメンバーを参照渡しで返すことができません
  • CS8345: フィールドまたは自動実装プロパティは、それが ref struct のインスタンス メンバーである場合を除いて、型にすることができません。
  • CS8351: ref 条件付きの演算子のブランチでは、互換性のない宣言スコープを持つ変数を参照できません
  • CS8374: ref 代入できません。ソースのエスケープ スコープが宛先よりも狭くなっています。
  • CS9077: ref パラメーターを介してパラメーターを参照渡しで返すことができません。それは return ステートメントでのみ返すことができます
  • CS9078: ref パラメーターを介してパラメーターのメンバーを参照渡しで返すことができません。それは return ステートメントでのみ返すことができます
  • CS9079: ソースは return ステートメントを介してのみ現在のメソッドをエスケープできるため、ソースを宛先に ref 代入できません。
  • CS9096: 宛先よりも広い値のエスケープ スコープがソースにあり、ソースよりも狭いエスケープ スコープを持つ値の宛先を介して代入が可能であるため、ソースを宛先に ref 代入できません。

警告:

  • CS9085: これはソースを宛先に ref 代入しますが、ソースのエスケープ スコープは宛先よりも狭くなっています。
  • CS9086: ref 条件付きの演算子のブランチでは、互換性のない宣言スコープを持つ変数を参照します
  • CS9087: これはパラメーターを参照返しで返しますが、ref パラメーターではありません
  • CS9089: これは、ref パラメーターでも out パラメーターでもないパラメーターのメンバーを参照渡しで返します
  • CS9091: これはローカルを参照渡しで返しますが、ref ローカルではありません
  • CS9092: これはローカルのメンバーを参照渡しで返しますが、ref ローカルではありません
  • CS9093: これはソースを宛先に ref 代入しますが、ソースは return ステートメントを介してのみ現在のメソッドをエスケープできます。
  • CS9094: これは ref パラメーターを介してパラメーターを参照渡しで返しますが、それは return ステートメントでのみ安全に返すことができます
  • CS9095: これは、ref パラメーターを介してパラメーターのメンバーを参照渡しで返しますが、それは return ステートメントでのみ安全に返すことができます
  • CS9097: これはソースを宛先に ref 代入しますが、宛先よりも広い値のスケープ スコープがソースにあり、ソースよりも狭いエスケープ スコープを持つ値の宛先を介して代入することができます。

コンパイラではスタティック分析を使用して、参照変数を使用できるすべてのポイントで参照先が有効かどうかを判断します。 参照変数が参照する可能性のあるすべての場所で、参照先が常に有効になるようにコードをリファクタリングする必要があります。 ref 安全性の規則の詳細については、ref safe context の C# 標準を参照してください。