次のエラーは、参照変数を使用しているときに生成されることがあります。
-
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パラメーターとしても渡すことはできません。 - 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" パラメーターは、具象 (非ジェネリック) 値の型である必要があります。 -
CS8373:
ref代入の左辺は ref 変数である必要があります。 -
CS8388:
out変数を ref ローカルとして宣言できません -
CS8977: "UnmanagedCallersOnly" 属性が設定されたメソッドのシグネチャでは、"
ref"、"in"、"out" のどれも使用できません。 - CS8986: パラメーターの 'scoped' 修飾子がターゲットと一致しません。
- CS8987: パラメーターの 'scoped' 修飾子が、オーバーライドされたメンバーまたは実装されたメンバーと一致しません。
- CS9061: 'scoped' 修飾子は破棄変数と一緒に使用することができません。
- CS9062: 型とエイリアスに 'scoped' という名前を付けることはできません。
- CS9063: UnscopedRefAttribute は既定でスコープ外であるため、このパラメーターに適用できません。
- CS9065: 'System.Runtime.CompilerServices.ScopedRefAttribute' を使用しないでください。代わりに 'scoped' キーワードを使用してください。
- CS9066: UnscopedRefAttribute は、'scoped' 修飾子を持つパラメーターには適用できません。
- CS9072: 分解変数を ref ローカルとして宣言できません
- CS9101: UnscopedRefAttribute は構造体または仮想インターフェイスのインスタンスのメソッドとプロパティにのみ適用でき、コンストラクターまたは初期化専用メンバーには適用できません。
- CS9102: 実装されるメンバーにこの属性がないため、インターフェイスの実装には UnscopedRefAttribute を適用できません。
-
CS9104: 型の
usingステートメント リソースは、非同期メソッドでも非同期ラムダ式でも使用できません。 -
CS9190:
readonly修飾子はrefの後に指定する必要があります。 -
CS9199:
ref readonlyパラメーターに Out 属性を指定することはできません。
参照変数が正しく使用されていない場合は、次の警告が生成されます。
- CS9073: パラメーターの 'scoped' 修飾子がターゲットと一致しません。
- CS9074: パラメーターの 'scoped' 修飾子が、オーバーライドされたメンバーまたは実装されたメンバーと一致しません。
-
CS9191:
refパラメーターに対応する引数のin修飾子はinと同じです。代わりにinを使用することを検討してください。 -
CS9192: 引数は
refまたはinキーワードと共に渡す必要があります。 -
CS9193: 引数は
ref readonlyパラメーターに渡されるため変数にする必要があります -
CS9195: 引数は
inキーワードと共に渡す必要があります - CS9196: パラメーターの参照種別修飾子が、オーバーライドまたは実装されたメンバーの対応するパラメーターと一致しません。
- CS9197: パラメーターの参照種別修飾子が、非表示のメンバーの対応するパラメーターと一致しません。
- CS9198: パラメーターの参照種別修飾子が、ターゲットの対応するパラメーターと一致しません。
-
CS9200:
ref readonlyパラメーターに既定値が指定されていますが、ref readonlyは参照にのみ使用する必要があります。そのパラメーターはinとして宣言することを検討してください。 - CS9201: 使用前に Ref フィールドに ref 代入する必要があります。
- CS9205: 補間文字列が必要です。
- CS9265: Field は参照割り当てされておらず、常に既定値 (null 参照) を持つことになります
これらのエラーと警告は、次のテーマに従います。
- 正しくない構文: 宣言または使用の構文が無効です。
-
ref変数が無効な言語コンストラクト: 一部の C# イディオムで変数が許可されていません。 通常、これは ref 安全性分析を確実に実行できないためです。 - 参照変数が必要な場合に使用される値式: 参照変数として使用される式は、値式ではなく変数である必要があります。
- 読み取り専用変数を参照する書き込み可能な参照変数: 読み取り専用変数への参照を、書き込み可能な参照で渡すことはできません。
この記事では、"参照変数" という用語が、in、ref readonly、ref、out 修飾子のいずれか、ref ローカル変数、ref の ref struct フィールド、または ref 戻り値で宣言されたパラメーターの一般的な用語として使用されます。 参照変数は、"参照先" と呼ばれる別の変数を参照します。
構文は正しくありません
これらのエラーは、参照変数に関して正しくない構文を使用していることを示します。
-
CS8373:
ref代入の左辺は ref 変数である必要があります。 -
CS8388:
out変数を ref ローカルとして宣言できません。 -
CS9190:
readonly修飾子はrefの後に指定する必要があります。 - CS9205: 補間文字列が必要です。
これらのエラーを修正するには:
-
= ref演算子の左オペランドが、値式または非参照ローカルではなく参照変数であることを確認します。 Ref 代入では、両方の辺が同じストレージ場所 (CS8373) のエイリアスを作成できる参照変数である必要があります。 - 参照パラメーターを宣言するときは、修飾子を
ref readonlyではなくreadonly refとして書き込みます。 C# 言語仕様では、すべての参照パラメーター型 (ref) 間で一貫した構文を維持するために、パラメーター宣言のreadonly修飾子の前に キーワードが必要です。 - ローカル参照変数を宣言するときは、
refの代わりにoutキーワードを使用します。outは、メソッドが返す前に値を割り当てる必要があることを示すパラメーター修飾子です。一方、refは、他のストレージの場所に別名を設定するローカル変数を作成するための適切なキーワードです (CS8388)。 -
outパラメーターを使用してメソッドを呼び出すときに、挿入文字列の代わりに、標準の変数または値式を渡します。 挿入文字列は不変の一時値であり、割り当て可能なストレージの場所 (CS9205) を表していないため、出力パラメーターとして使用できません。
参照変数とその構文要件の詳細については、 参照変数 と C# 言語仕様を参照してください。
参照変数の制限
次のエラーは、参照変数が存在する場合は参照変数を使用できないことを示しています。
-
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 参照) を持つことになります
これらのエラーを修正するには:
- インデクサーから参照パラメーターを削除します。 インデクサーは配列に似たアクセス構文を提供するように設計されており、コンパイラはインデクサー アクセサー (CS0631、 CS1623) を介して渡される参照の安全な有効期間追跡を保証できません。
- 反復子メソッドから参照パラメーターを削除します。 反復子はステート マシンを使用して複数の呼び出しでコードを遅延実行します。コンパイラは、実行が中断および再開される yield 戻り境界を越えて参照される変数が有効であることを保証できません (CS1623)。
- 非同期メソッドから参照パラメーターを削除します。 非同期メソッドは、待機ポイントでの実行を中断し、異なるスレッドで再開する可能性があるため、参照される変数が有効であり、メソッドの実行全体でアクセス可能であることを保証することはできません (CS1988)。
- await 式をref 条件式内で使用しないでください。 await 操作では、実行が中断され、条件演算子によって選択されている参照が無効になり、実行が再開されたときに無効な参照が使用される可能性があります (CS8325)。
- ref 条件演算子の両方の分岐が参照を返すか、どちらも参照を返さないようにし、両方が参照である場合は同じ型にする必要があります。 条件付き演算子は、選択されている分岐 (CS8326、 CS8327) に関係なく、呼び出し元のコードで安全に使用できる一貫性のある結果の型を生成する必要があります。
-
refパラメーターとoutパラメーターから既定値を削除します。 パラメーターと既存の変数の間に必要なエイリアス関係を確立するには、常に呼び出しサイトで参照パラメーターを指定する必要があります。既定値は意味を持たない (CS1741)。 - 同じ変数も参照する引数リストで、暗黙的に型指定された
out変数を宣言しないでください。 コンパイラは、同じ式内でその変数の使用を同時に検証しながら、メソッド シグネチャから変数の型を推論し、循環依存関係 (CS8196) を作成する必要があります。 - LINQ クエリ範囲変数を参照パラメーターとして渡さないでください。 範囲変数は、クエリ実行モデルによって有効期間が管理され、安全に参照できる安定したメモリ位置を持たないコンパイラによって生成される反復変数です (CS1939)。
- オブジェクトを分解するときは、ref ローカルの代わりに標準値変数 を 使用します。 分解では、分解された値を受け取る新しい変数が作成されます。参照変数は、個別に格納するのではなく、これらの一時値のエイリアスを試みます (CS9072)。
- メソッドがパラメーターに対して
refとout修飾子によってのみ異なる複数のインターフェイスを実装しないようにします。 C# 言語仕様では、これらを個別のシグネチャとして扱いますが、refとoutの両方が実装境界で同じ呼び出し構文を共有するため、呼び出す実装を明確にする方法は提供されません (CS0767)。 - System.Runtime.InteropServices.UnmanagedCallersOnlyAttributeで修飾されたメソッドから参照パラメーターを削除します。 これらのメソッドは、C# の参照安全規則を理解していないアンマネージ コードから呼び出すことができ、マネージド/アンマネージド境界 (CS8977) 全体で参照される変数の適切な有効期間管理を保証することはできません。
-
refの最初のパラメーターには、値型または値型に制約されたジェネリック型にのみ、修飾子を使用します。 参照型は既に CLR レベルで参照渡しされており、refを追加すると参照への参照が作成されますが、refを持つ値型拡張では拡張インスタンスの変更が有効になります (CS8337、 CS8338)。 - 参照パラメーターとして Windows ランタイム イベントを渡さないでください。 これらのイベントは Windows ランタイム型システムに従います。これは、.NET 参照とは有効期間とスレッドセマンティクスが異なり、C# 参照パラメーター (CS7084) で必要なエイリアス動作をサポートしていません。
- パラメーターからSystem.Runtime.InteropServices.OutAttribute
ref readonly削除します。 この属性は、パラメーターの方向がアウトバウンドのみのプラットフォーム呼び出しシナリオでセマンティクスをマーシャリングするように設計されています。これは、パラメーターが再割り当てされない既存のデータを参照するというref readonlyの保証と競合します (CS9199)。 - コンストラクターが完了する前に、型のすべての
refフィールドがフィールド初期化子またはすべてのコンストラクター コード パスで割り当てられていることを確認します。 初期化されていない ref フィールドには無効な参照が含まれるので、アクセスするとメモリが破損する可能性があります (CS9201、 CS9265)。 - メソッドとオーバーライドされた基本メソッドまたは実装されたインターフェイス メソッドの間で、参照の種類修飾子 (
ref、in、out、ref readonly) を照合します。 参照修飾子は、置換可能性と呼び出し元の期待を維持するために派生型が受け入れる必要があるメソッド シグネチャ コントラクトの一部です (CS9196、 CS9197、 CS9198)。 - 既定値を指定するときに
inするのではなく、パラメーターをref readonlyとして宣言します。ref readonlyは、呼び出し元が既存の変数への参照を渡すシナリオ向けに設計されています。一方、inパラメーターは値の参照と一時コピーの両方を受け入れることができ、既定値は意味のあるものになります (CS9200)。
参照変数を使用できる場所の詳細については、「 メソッド パラメーター、 反復子、 非同期プログラミング パターン、 および C# 言語仕様」を参照してください。
unscoped ref 制約
unscoped パラメーターの ref 修飾子は、一部の場所では許可されていません。
- CS9101: UnscopedRefAttribute は、構造体インスタンスまたは仮想インターフェイスのメソッドとプロパティにのみ適用でき、コンストラクターまたは init 専用メンバーには適用できません。
- CS9102: 実装されるメンバーにはこの属性がないため、UnscopedRefAttribute をインターフェイス実装に適用できません。
これらのエラーを修正するには:
- 構造体コンストラクターと init のみのメンバーから、
unscoped修飾子または System.Diagnostics.CodeAnalysis.UnscopedRefAttribute 属性を削除します。 これらのメンバーには特別な初期化セマンティクスがあります。この場合、コンパイラは参照が初期化フェーズを超えないようにする必要があり、スコープなし参照を許可すると、構造体が完全にアクセスできるようになる前に初期化が完了するという保証に違反します (CS9101)。 - 対応するインターフェイス メソッドに
unscoped修飾子がない場合は、インターフェイス実装メソッドから削除します。 スコープ外の特性は、参照の有効期間保証に関するメソッドのコントラクトに影響を与えます。実装にあたっては、呼び出し元が一貫した有効期間の動作に依存できるように、どの実装が呼び出されるか (CS9102) に関係なく、実装されるインターフェイスと同様のコントラクトを維持する必要があります。
スコープ付き参照とスコープなし参照の詳細については、 メソッド パラメーター と 低レベル構造体の機能強化 機能仕様に関するページを参照してください。
参照変数には参照先が必要
参照パラメーター、参照戻り値、ref ローカル代入のいずれかの引数として変数を指定する必要があります。
-
CS0206: 参照を返さないプロパティまたはインデクサーは
out値としてもref値としても使用できません -
CS1510:
refまたはout値は、割り当て可能な変数でなければなりません
警告:
-
CS9191:
refパラメーターに対応する引数のin修飾子はinと同じです。代わりにinを使用することを検討してください。 -
CS9192: 引数は
refまたはinキーワードと共に渡す必要があります。 -
CS9193: 引数は
ref readonlyパラメーターに渡されるため変数にする必要があります -
CS9195: 引数は
inキーワードと共に渡す必要があります
これらのエラーを修正するには:
- プロパティまたはインデクサー アクセスの結果を参照パラメーターとして渡す前に、ローカル変数に格納します。 プロパティ と インデクサー は、ストレージの場所に直接アクセスするのではなく値を返すメソッドであり、参照パラメーターには、エイリアス化できる安定したメモリ位置を持つ実際の変数が必要です (CS0206、 CS1510)。
- パラメーターに引数を渡すときに
inの代わりに、ref修飾子in使用します。ref下位互換性のために技術的に機能しますが、in修飾子は、引数が読み取り専用であり、コピーせずに参照としてより効率的に渡される可能性があることを明確に表します (CS9191、CS9195)。 - 参照を想定するパラメーターに引数を渡すときに、適切な参照修飾子 (
ref、in、またはref readonly) を追加します。 修飾子を省略すると、コンパイラによって値の一時的なコピーが作成される可能性があります。これは非効率的であり、呼び出し元のコードで変更が元の変数 (CS9192、 CS9193) に反映されると予期しない動作を引き起こす可能性があります。
参照パラメーターと参照渡し変数の詳細については、「 メソッド パラメーター、 ref キーワード、および C# 言語仕様」を参照してください。
書き込み可能な参照変数には書き込み可能な参照先が必要
書き込み可能な参照変数では、参照先も書き込み可能である必要があります。 次のエラーは、変数が書き込み可能ではないことを示しています。
-
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代入の右辺として使用することもできません
これらのエラーを修正するには:
-
値を読み取り専用フィールドからローカル変数にコピーし、ローカル変数を
refまたはoutパラメーターとして渡します。 読み取り時フィールドは初期化後 (コンストラクター内を除く) 変更不可であり、それらのフィールドへの書き込み可能な参照を許可すると、読み取り時に提供される不変性の保証に違反します (CS0192、 CS0199、 CS1649、 CS1651)。 - 参照によって読み取り専用変数、反復変数、またはその他の書き込み不可能な値を渡す必要がある場合は、
ref readonlyまたはinの代わりに、refまたはoutパラメーターを使用します。 これらの修飾子は、メソッドが参照先の値のみを読み取り、変更を試みない状態であることを示します。 これは、元の変数 (CS1605、CS1655、CS1657、CS8329) の不変性制約と一致します。 - 書き込み可能な参照として渡す前に、読み取り時の変数のメンバーをローカル変数にコピーします。 メンバー自体が読み取り専用として宣言されていない場合でも、読み取り専用パス (読み取り専用フィールド、
inパラメーター、またはref readonlyローカルを介して) を介してアクセスされ、コンパイラは読み取り専用データ (CS8330、 CS8332) の間接的な変更を防ぐために読み取り専用性の推移性を強制します。 - 読み取り可能な変数、 foreach 反復変数、 ステートメント リソースの使用、または 固定ステートメント変数への書き込み可能な ref 代入は避けてください。 これらの変数には、コンパイラによって管理される特別な有効期間セマンティクスがあります。 変数は自動的に最終処理されるか、スコープの最後に破棄されます。 外部参照では、破棄後に未解決の参照が作成されます (CS8331)。
読み取り時セマンティクスと参照パラメーターの詳細については、readonly キーワード (パラメーター修飾子、ref readonly、C# 言語仕様) を参照してください。
.NET