参照パラメーター、変数、戻り値に関連付けられているエラーと警告
次のエラーは、参照変数を使用しているときに生成されることがあります。
- CS0192:
readonly
フィールドはref
値としてもout
値としても使用できません (コンストラクターでは可) - CS0199:
static readonly
フィールドはref
値としてもout
値としても使用できません (静的コンストラクターでは可) - CS0206: 参照を返さないプロパティまたはインデクサーは
out
値としてもref
値としても使用できません - CS0631:
ref
とout
はこのコンテキストでは無効です - CS0767:
ref
とout
についてのみ相違があるオーバーロードがメソッドに含まれるようになるため、指定した型パラメーターを持つインターフェイスを継承できません - CS1510:
ref
またはout
値は、割り当て可能な変数でなければなりません - CS1605: 変数は読み取り専用であるため、
ref
値としてもout
値としても使用できません - CS1623: 反復子には
ref
、in
、out
のどのパラメーターも指定できません - CS1649:
readonly
フィールドのメンバーはref
値としてもout
値としても使用できません (コンストラクターでは可) - CS1651: 静的な読み取り専用フィールドのフィールドは
ref
値としてもout
値としても使用できません (静的コンストラクターでは可) - CS1655: 型のフィールドは
ref
値としてもout
値としても使用できません - CS1657: 変数は
ref
値としてもout
値としても使用できません - CS1741:
ref
とout
のどちらのパラメーターにも既定値を指定できません - CS1939: 範囲変数は
out
パラメーターとしてもref
パラメーターとしても渡すことはできません - CS1988: 非同期メソッドには
ref
、in
、out
のどのパラメーターも指定できません - 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 参照) を持つことになります
これらのエラーと警告は、次のテーマに従います。
- 正しくない構文: 宣言または使用の構文が無効です。
ref
変数が無効な言語コンストラクト: 一部の C# イディオムで変数が許可されていません。 通常、これは ref 安全性分析を確実に実行できないためです。- 参照変数が必要な場合に使用される値式: 参照変数として使用される式は、値式ではなく変数である必要があります。
- 読み取り専用変数を参照する書き込み可能な参照変数: 読み取り専用変数への参照を、書き込み可能な参照で渡すことはできません。
- ref 安全性の違反: 参照変数は、より狭いコンテキストを持つ変数を参照できません。 これは、参照変数が無効なメモリを参照できることを意味します。
この記事では、"参照変数" という用語が、in
、ref readonly
、ref
、out
修飾子のいずれか、ref
ローカル変数、ref struct
の ref
フィールド、または ref
戻り値で宣言されたパラメーターの一般的な用語として使用されます。 参照変数は、"参照先" と呼ばれる別の変数を参照します。
構文は正しくありません
これらのエラーは、参照変数に関して正しくない構文を使用していることを示します。
- CS8373:
ref
代入の左辺は ref 変数である必要があります。 - CS8388:
out
変数を ref ローカルとして宣言できません。 - CS9190:
readonly
修飾子はref
の後に指定する必要があります。
次のいずれかの変更でエラーを修正できます。
= ref
演算子の左オペランドは参照変数である必要があります。 正しい構文の詳細については、「参照変数」を参照してください。- パラメーター修飾子
ref readonly
は、その順序である必要があります。readonly ref
は有効なパラメーター修飾子ではありません。 単語の順序を切り替えてください。 - ローカル変数を
out
として宣言することはできません。 ローカル参照変数を宣言するには、ref
を使用します。
参照変数の制限
次のエラーは、参照変数が存在する場合は参照変数を使用できないことを示しています。
- CS0631:
ref
とout
はこのコンテキストでは無効です - CS0767:
ref
とout
についてのみ相違があるオーバーロードがメソッドに含まれるようになるため、指定した型パラメーターを持つインターフェイスを継承できません - CS1623: 反復子には
ref
、in
、out
のどのパラメーターも指定できません - CS1741:
ref
とout
のどちらのパラメーターにも既定値を指定できません - CS1939: 範囲変数は
out
パラメーターとしてもref
パラメーターとしても渡すことはできません - CS1988: 非同期メソッドには
ref
、in
、out
のどのパラメーターも指定できません - 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 参照) を持つことになります
エラーを修正するには、参照変数が許可されていない場合は、それを削除します。
- インデクサー、反復子、および非同期メソッドから、
in
、ref
、およびout
パラメーターを削除します。 - await を含む
? :
ref 条件式 () を削除します。 - 型が値の型でない、または値の型として制約されているジェネリック型でない場合、拡張メソッドの最初のパラメーターから
ref
修飾子を削除します。 - [条件付きの演算子式] の両方が
ref
変数である必要があります。あるいは、どちらもその変数であってはなりません。 いずれかの式からref
を削除するか、もう一方の式にそれを追加します。ref
条件式の場合、両方の式が同じ型である必要があります。 ref
とout
の両方のパラメーターには既定値を指定できません。ref
またはout
のいずれかの修飾子を削除するか、既定値を削除します。- 暗黙的に型指定された
out
変数宣言は、同じ引数リスト内の他の場所にも表示できません。 async
メソッドのラムダ式のusing
ステートメントには参照変数を配置できません。- LINQ クエリ式の範囲変数を参照渡しすることはできません。
- オブジェクトを参照変数に分解することはできません。 参照変数を値変数に置き換えてください。
- メソッドのオーバーロードで
ref
とout
についてのみ相違がある場合、複数のインターフェイスを実装することはできません。 たとえば、あるインターフェイスで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# 標準を参照してください。
.NET