CS2001~

C# コンパイラ エラー CS8173 の原因と解決方法について解説

CS8173はC#のコンパイラエラーです。

参照渡しで変数を割り当てる際、変数の型が一致しない場合に発生します。

例えば、ref string変数をref object変数に割り当てようとするとエラーとなります。

エラーメッセージに従い、変数の型を正しく一致させることで解消できます。

CS8173エラーの発生原因

参照渡しの基本ルール

C#において参照渡しを行う場合、変数を参照として割り当てる際のルールが厳格に定められています。

参照渡しでは、参照先の変数の型と参照変数の型が完全に一致している必要があります。

たとえば、変数string sに対してref string rs = ref s;とするのは問題ありませんが、型が異なる場合にはコンパイラがエラーを通知してくれます。

参照渡しにおける型の制約

C#では、参照渡しに使用される変数は以下の制約を遵守する必要があります。

  • 変数同士の型が完全に一致していること
  • 変数が参照可能な状態であること

これらの制約は、意図しない型変換や型の不一致による予期せぬ動作を防ぐために存在します。

たとえば、以下のサンプルコードでは、string型の変数strを参照変数refStrに正しく割り当てる方法が示されています。

using System;
class Program
{
    static void Main()
    {
        string str = "参照渡しサンプル";
        // 正しい参照渡し。型が一致しているため問題はありません。
        ref string refStr = ref str;
        Console.WriteLine(refStr);
    }
}
参照渡しサンプル

変数への参照代入時の型一致要求

参照の代入時には、変数の型がまったく同じでなければなりません。

これは、C#が型安全性を厳密に管理しているためであり、型の違いによるバグや実行時エラーを防ぐための仕組みです。

たとえば、object型の変数に対してstring型の参照を割り当てると、型が一致しないためCS8173エラーが発生します。

したがって、参照先と参照変数の型が一致するかどうかを常に確認することが大切です。

型不一致によるエラー発生ケース

C#では、表面的には互換性がありそうな型同士でも、参照渡しにおいては厳密な一致が求められるため、型不一致がエラーを招くケースがあります。

stringとobjectの違い

C#では、string型はobject型の派生型であるため、通常の代入では問題なく動作します。

以下のように、string s = "文字列";からobject o = s;という代入は許容されます。

しかし、参照渡しの場合は状況が異なります。

たとえば、ref object ro = ref o;という参照変数に対して、ro = ref s;としようとすると、osで型が異なるため、CS8173エラーが発生します。

これは、参照渡しにおいて型の変更が許されていないためです。

記述ミスによる発生パターン

プログラミング中に発生するエラーの中には、単純な記述ミスや誤った変数の参照によって引き起こされる場合もあります。

たとえば、開発中にrefキーワードの使い方を誤り、以下のようなコードを書いてしまうとエラーが発生します。

using System;
class Program
{
    static void Main()
    {
        string s = "文字列例";
        object o = s;
        // 以下はエラー。型が一致しないためCS8173が発生します。
        // ref object ro = ref o;
        // ro = ref s;
    }
}

このような場合は、参照渡しの対象となる変数の型が正しく一致しているかどうかを確認し、正しい型の変数に参照を割り当てる必要があります。

CS8173エラーの解決方法

正しい参照変数の代入方法

正しい参照変数の代入方法とは、参照渡しを行う際に常に変数の型が一致するようにコードを書くことです。

参照先と参照変数で型が一致していれば、エラーを回避できます。

また、コードの可読性や保守性も向上します。

型の一致による代入ルールの適用

参照渡しでは、必ず対象の変数と参照変数の型が同じであることを確認します。

型の一致とは、例えばstring型で定義された変数同士ならば、そのままの参照渡しが可能であり、型変換や中間変数を介する必要はありません。

C#の型システムがこのルールを厳格に適用しているため、正しい型を用いた参照渡しが求められます。

以下のサンプルコードでは、正しくstring型の変数を参照渡しする例が示されています。

using System;
class Program
{
    static void Main()
    {
        string original = "正しい参照渡し";
        // 型が一致しているため、エラーは発生しません。
        ref string referenceVar = ref original;
        Console.WriteLine(referenceVar);
    }
}
正しい参照渡し

具体例を用いた修正手法

実際にCS8173エラーが発生した場合の具体例として、以下のコードをご確認ください。

この例では、string型の変数に対して不適切な型(object型)で参照を割り当てようとしてエラーが発生しています。

using System;
class Program
{
    static void Main()
    {
        string s = "文字列例";
        object o = s;
        // 以下の参照渡しはエラーとなるため、修正が必要です。
        // ref object ro = ref o;
        // ro = ref s;
        // 正しい方法: 参照変数の型を`string`に合わせます。
        ref string rs = ref s;
        rs = ref s;
        Console.WriteLine(rs);
    }
}
文字列例

このように、コンパイラがエラーメッセージを出力した場合は、参照を割り当てる変数の型を再確認し、必ず一致する型を使用するように修正してください。

エラーメッセージからの対処法

エラーメッセージは、どの部分が原因でエラーになっているのかを正確に示してくれます。

CS8173エラーの場合も、参照渡しで割り当てられる変数の型が不一致であることを明確に指摘されています。

エラーメッセージを正しく読み解くことで、修正すべき箇所が明確になります。

メッセージの読み取りポイント

CS8173エラーが示すメッセージには、「式は参照渡しで割り当てられるため、型 T でなければならない」といった内容が含まれています。

ここでTに該当する型が、参照渡しにおいて必ず一致しなければならない型です。

これにより、どの変数の型が誤っているのかを把握することができます。

コンパイラ指摘内容の確認と修正方法

コンパイラは、指摘された箇所の変数の型が一致していない点を明示します。

たとえば、ref object ro = ref o;の後にro = ref s;と記述している場合、object型とstring型の不一致が原因です。

この場合の修正方法は、参照変数の型をstringに揃えるか、もしくは参照元の変数の型を変更することです。

エラーメッセージを参照し、型一致のルールに則ってコードを見直すことが重要です。

まとめ

この記事では、C#の参照渡しにおいて変数の型が一致していなければならないルールを解説しています。

参照変数を宣言する際、型の不一致がCS8173エラーを引き起こすこと、string型とobject型の違いや記述ミスによるエラー発生の事例を具体例とともに説明しました。

正しい型を用いた参照代入方法とエラーメッセージの読み取り方についても紹介しています。

関連記事

Back to top button