CS0~400

C# コンパイラ エラー CS0135 の原因と対策を解説

CS0135は、C#で同じ名前のローカル変数を再定義した場合に発生するコンパイルエラーです。

特に、入れ子になったブロック内で外側の変数と同名の変数を定義すると、名前の衝突が起こりエラーとなります。

宣言領域ごとに変数名を見直すことで対処できます。

エラー CS0135 の基本

エラーの定義と特徴

名前の隠蔽による競合現象

エラー CS0135 は、同じスコープ内または入れ子のスコープで同名の変数を宣言した場合に発生します。

これは、内側のブロックで宣言された変数が外側の変数の名前を隠してしまう「名前の隠蔽」に起因する現象です。

C# は、ロジックエラーを未然に防ぐため、同じ宣言領域内での重複を許容しません。

C# のローカル変数宣言ルール

C# のコンパイラは、同一の宣言領域またはその内側の領域で同じ名前のローカル変数を再定義することを禁止しています。

これは、以下のようなサンプルコードで確認できます。

// サンプルコード: CS0135 が発生する例
public class SampleClass
{
    public static int counter = 0;
    public static void Main()
    {
        {
            // 外側の counter と同名のローカル変数を定義しているためエラーになる
            int counter = 5;
            counter++;
        }
        counter = 0;
    }
}
コンパイルエラー: 'counter' は既に他の宣言で使用されています。

このように、同じ変数名を異なるスコープで使うと、意図しない競合が起こりやすくなります。

入れ子ブロックにおける宣言構造

宣言領域間の関係と制約

C# では、変数の宣言領域はブロック(中括弧で囲まれる部分)ごとに決まります。

外側のブロックで宣言された変数は内側でも参照可能ですが、内側で同名の変数を新たに定義すると外側の変数が隠蔽されます。

これにより、意図せず外側の変数と混同するリスクがあり、コンパイラもこれをエラーとして検出します。

例えば、次のようなコードの場合、内側で定義された変数が外側の変数と同じ名前だとエラーが発生します。

// サンプルコード: 入れ子ブロックにおける同名変数の宣言例
public class ScopeExample
{
    public static int number = 10;
    public static void Main()
    {
        {
            // 内側で数値を再定義するためエラーとなる
            int number = 20;
            System.Console.WriteLine("内側の number: " + number);
        }
        System.Console.WriteLine("外側の number: " + number);
    }
}
コンパイルエラー: 'number' は既に他の宣言で使用されています。

このように、変数の宣言領域の関係が原因で、意図しない名前の重複が発生することがあります。

発生原因の詳細解説

入れ子ブロックでの変数再定義

競合が生じる宣言パターン

入れ子ブロックの構造により、外側のブロックで定義された変数と内側のブロックで同じ変数名が再び使用されると、競合状態が発生します。

特に、外側でグローバルな変数やクラスレベルの変数を定義している場合、内部のローカル変数と名前が重複するとエラー CS0135 が出現します。

以下の例では、外側の value と内側の value が同一視され、エラーとなります。

// サンプルコード: 入れ子ブロックでの変数再定義例
public class VariableConflict
{
    public static int value = 100;
    public static void Main()
    {
        {
            // 内側で value を再定義して競合が発生する
            int value = 50;
            System.Console.WriteLine("内側の value: " + value);
        }
        System.Console.WriteLine("外側の value: " + value);
    }
}
コンパイルエラー: 'value' は既に他の宣言で使用されています。

C# 言語仕様に基づくエラーの仕組み

宣言領域の範囲と制限

C# の言語仕様では、変数の宣言領域はブロック単位で決定されます。

例えば、外側のブロックで宣言された変数は内側のブロックでも参照可能ですが、内側で同じ名前で宣言するとコンパイラはこれをエラーと判断します。

数式で表すと、ブロックの宣言領域を Douter とし、内側の宣言領域を Dinner とすると、

DinnerDouter

このとき、Dinner 内で x を新たに宣言すると、Douter で宣言された x は隠蔽され、混乱を招く恐れがあります。

具体的には、以下のコード例で示されるように、外側と内側で同じ名前の変数が存在するとコンパイラエラーが発生します。

// サンプルコード: 宣言領域の範囲を示す例
public class DeclarationScope
{
    public static int data = 10;
    public static void Main()
    {
        {
            // 内側のブロックでの再定義はエラー原因となる
            int data = 20;
            System.Console.WriteLine("内側の data: " + data);
        }
        System.Console.WriteLine("外側の data: " + data);
    }
}
コンパイルエラー: 'data' は既に他の宣言で使用されています。

この仕組みは、プログラム内での変数の参照関係を明確にし、予期せぬ動作を防ぐために設けられています。

エラー CS0135 の対策と解決方法

変数名の見直しと変更方法

適切な命名規則の適用

エラー CS0135 が発生した場合、最もシンプルな対策は変数名を変更することです。

同一スコープ内で同じ名前を利用せず、各変数に対して意味のある名前を付けることで、長期的な保守性も向上します。

例えば、内側の変数には接頭語や接尾語を付与して区別する方法が有効です。

// サンプルコード: 変数名を変更して競合を解消する例
public class NamingConventionExample
{
    public static int globalValue = 100;
    public static void Main()
    {
        {
            // 内側の変数名に接頭語を追加してグローバル変数と区別する
            int localValue = 50;
            System.Console.WriteLine("内側の localValue: " + localValue);
        }
        System.Console.WriteLine("グローバルな globalValue: " + globalValue);
    }
}
内側の localValue: 50
グローバルな globalValue: 100

宣言領域の整理手法

変数の宣言位置を見直すことも有効な対策です。

不要な入れ子構造を避け、変数が必要なスコープ内でのみ宣言するように整理することで、重複宣言による競合を回避できます。

また、同じ名前の変数が混在しないように、ブロックごとに責任範囲を明確に分けると理解しやすくなります。

対処時の注意点

実例を通した対策手順

実際の開発現場では、以下の対策手順を意識することが役立ちます。

・エラーが表示された場合、変数の宣言場所とスコープを確認する

・内側のブロックと外側のブロックで同じ名前が使用されていないか確認する

・変数名に意味のある名前を付け、衝突を防ぐ

・コードの可読性を考慮し、必要に応じてブロックの構造を再編成する

以下に、対策を反映させたサンプルコードを示します。

// サンプルコード: エラー回避のための対策実例
public class ConflictResolution
{
    public static int baseValue = 100;
    public static void Main()
    {
        {
            // 内側の変数名を変更し、衝突を回避する
            int innerValue = 50;
            System.Console.WriteLine("内側の innerValue: " + innerValue);
        }
        System.Console.WriteLine("基底の baseValue: " + baseValue);
    }
}
内側の innerValue: 50
基底の baseValue: 100

このように変数名を整理し、宣言領域を適切に管理することで、エラー CS0135 を回避することができます。

まとめ

この記事では、エラー CS0135 の定義や特徴、名前の隠蔽が引き起こす競合現象、そして入れ子ブロックにおける宣言の制約について解説しました。

また、実際のコード例を用いながら、変数名の変更や宣言領域の整理による対策方法と注意点について説明しました。

この記事を通じて、同じスコープ内での変数の重複宣言を回避する基本原則が理解できるようになります。

関連記事

Back to top button
目次へ