次の方法で共有


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

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

  • 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 パラメーターとしても渡すことはできません。
  • 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 参照) を持つことになります

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

この記事では、"参照変数" という用語が、inref readonlyrefout 修飾子のいずれか、ref ローカル変数、refref 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: 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 参照) を持つことになります

これらのエラーを修正するには:

  • インデクサーから参照パラメーターを削除します。 インデクサーは配列に似たアクセス構文を提供するように設計されており、コンパイラはインデクサー アクセサー (CS0631CS1623) を介して渡される参照の安全な有効期間追跡を保証できません。
  • 反復子メソッドから参照パラメーターを削除します。 反復子はステート マシンを使用して複数の呼び出しでコードを遅延実行します。コンパイラは、実行が中断および再開される yield 戻り境界を越えて参照される変数が有効であることを保証できません (CS1623)。
  • 非同期メソッドから参照パラメーターを削除します。 非同期メソッドは、待機ポイントでの実行を中断し、異なるスレッドで再開する可能性があるため、参照される変数が有効であり、メソッドの実行全体でアクセス可能であることを保証することはできません (CS1988)。
  • await 式ref 条件式内で使用しないでください。 await 操作では、実行が中断され、条件演算子によって選択されている参照が無効になり、実行が再開されたときに無効な参照が使用される可能性があります (CS8325)。
  • ref 条件演算子の両方の分岐が参照を返すか、どちらも参照を返さないようにし、両方が参照である場合は同じ型にする必要があります。 条件付き演算子は、選択されている分岐 (CS8326CS8327) に関係なく、呼び出し元のコードで安全に使用できる一貫性のある結果の型を生成する必要があります。
  • refパラメーターとout パラメーターから既定値を削除します。 パラメーターと既存の変数の間に必要なエイリアス関係を確立するには、常に呼び出しサイトで参照パラメーターを指定する必要があります。既定値は意味を持たない (CS1741)。
  • 同じ変数も参照する引数リストで、暗黙的に型指定された out 変数を宣言しないでください。 コンパイラは、同じ式内でその変数の使用を同時に検証しながら、メソッド シグネチャから変数の型を推論し、循環依存関係 (CS8196) を作成する必要があります。
  • LINQ クエリ範囲変数を参照パラメーターとして渡さないでください。 範囲変数は、クエリ実行モデルによって有効期間が管理され、安全に参照できる安定したメモリ位置を持たないコンパイラによって生成される反復変数です (CS1939)。
  • オブジェクトを分解するときは、ref ローカルの代わりに標準値変数 使用します。 分解では、分解された値を受け取る新しい変数が作成されます。参照変数は、個別に格納するのではなく、これらの一時値のエイリアスを試みます (CS9072)。
  • メソッドがパラメーターに対して refout 修飾子によってのみ異なる複数のインターフェイスを実装しないようにします。 C# 言語仕様では、これらを個別のシグネチャとして扱いますが、 refout の両方が実装境界で同じ呼び出し構文を共有するため、呼び出す実装を明確にする方法は提供されません (CS0767)。
  • System.Runtime.InteropServices.UnmanagedCallersOnlyAttributeで修飾されたメソッドから参照パラメーターを削除します。 これらのメソッドは、C# の参照安全規則を理解していないアンマネージ コードから呼び出すことができ、マネージド/アンマネージド境界 (CS8977) 全体で参照される変数の適切な有効期間管理を保証することはできません。
  • refの最初のパラメーターには、値型または値型に制約されたジェネリック型にのみ、修飾子を使用します。 参照型は既に CLR レベルで参照渡しされており、 ref を追加すると参照への参照が作成されますが、 ref を持つ値型拡張では拡張インスタンスの変更が有効になります (CS8337CS8338)。
  • 参照パラメーターとして Windows ランタイム イベントを渡さないでください。 これらのイベントは Windows ランタイム型システムに従います。これは、.NET 参照とは有効期間とスレッドセマンティクスが異なり、C# 参照パラメーター (CS7084) で必要なエイリアス動作をサポートしていません。
  • パラメーターからSystem.Runtime.InteropServices.OutAttributeref readonly削除します。 この属性は、パラメーターの方向がアウトバウンドのみのプラットフォーム呼び出しシナリオでセマンティクスをマーシャリングするように設計されています。これは、パラメーターが再割り当てされない既存のデータを参照するという ref readonlyの保証と競合します (CS9199)。
  • コンストラクターが完了する前に、型のすべての ref フィールドがフィールド初期化子またはすべてのコンストラクター コード パスで割り当てられていることを確認します。 初期化されていない ref フィールドには無効な参照が含まれるので、アクセスするとメモリが破損する可能性があります (CS9201CS9265)。
  • メソッドとオーバーライドされた基本メソッドまたは実装されたインターフェイス メソッドの間で、参照の種類修飾子 (refinoutref readonly) を照合します。 参照修飾子は、置換可能性と呼び出し元の期待を維持するために派生型が受け入れる必要があるメソッド シグネチャ コントラクトの一部です (CS9196CS9197CS9198)。
  • 既定値を指定するときに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 キーワードと共に渡す必要があります

これらのエラーを修正するには:

  • プロパティまたはインデクサー アクセスの結果を参照パラメーターとして渡す前に、ローカル変数に格納します。 プロパティインデクサー は、ストレージの場所に直接アクセスするのではなく値を返すメソッドであり、参照パラメーターには、エイリアス化できる安定したメモリ位置を持つ実際の変数が必要です (CS0206CS1510)。
  • パラメーターに引数を渡すときにinの代わりに、ref修飾子in使用します。 ref下位互換性のために技術的に機能しますが、in修飾子は、引数が読み取り専用であり、コピーせずに参照としてより効率的に渡される可能性があることを明確に表します (CS9191CS9195)。
  • 参照を想定するパラメーターに引数を渡すときに、適切な参照修飾子 (refin、または ref readonly) を追加します。 修飾子を省略すると、コンパイラによって値の一時的なコピーが作成される可能性があります。これは非効率的であり、呼び出し元のコードで変更が元の変数 (CS9192CS9193) に反映されると予期しない動作を引き起こす可能性があります。

参照パラメーターと参照渡し変数の詳細については、「 メソッド パラメーター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 パラメーターとして渡します。 読み取り時フィールドは初期化後 (コンストラクター内を除く) 変更不可であり、それらのフィールドへの書き込み可能な参照を許可すると、読み取り時に提供される不変性の保証に違反します (CS0192CS0199CS1649CS1651)。
  • 参照によって読み取り専用変数、反復変数、またはその他の書き込み不可能な値を渡す必要がある場合は、ref readonlyまたはinの代わりに、refまたはoutパラメーターを使用します。 これらの修飾子は、メソッドが参照先の値のみを読み取り、変更を試みない状態であることを示します。 これは、元の変数 (CS1605、CS1655CS1657CS8329) の不変性制約と一致します。
  • 書き込み可能な参照として渡す前に、読み取り時の変数のメンバーをローカル変数にコピーします。 メンバー自体が読み取り専用として宣言されていない場合でも、読み取り専用パス (読み取り専用フィールド、 in パラメーター、または ref readonly ローカルを介して) を介してアクセスされ、コンパイラは読み取り専用データ (CS8330CS8332) の間接的な変更を防ぐために読み取り専用性の推移性を強制します。
  • 読み取り可能な変数、 foreach 反復変数ステートメント リソースの使用、または 固定ステートメント変数への書き込み可能な ref 代入は避けてください。 これらの変数には、コンパイラによって管理される特別な有効期間セマンティクスがあります。 変数は自動的に最終処理されるか、スコープの最後に破棄されます。 外部参照では、破棄後に未解決の参照が作成されます (CS8331)。

読み取り時セマンティクスと参照パラメーターの詳細については、readonly キーワード (パラメーター修飾子、ref readonlyC# 言語仕様) を参照してください。