C# コンパイラエラー CS0120 の原因と対策について解説
CS0120エラーは、C#で静的メソッドから非静的なフィールドやメソッド、プロパティに直接アクセスしようとした場合に発生します。
非静的メンバーにはインスタンスが必要であるため、まずオブジェクトを生成してからそのインスタンス経由でアクセスするか、必要に応じてメンバーを静的に変更することでエラーを解消できます。
CS0120エラーの概要
CS0120エラーとは
CS0120エラーは、C#のコンパイラが「非静的(インスタンス)メンバーを静的コンテキストから呼び出そうとした」場合に発生するエラーです。
つまり、非静的なフィールド、メソッド、またはプロパティにアクセスする際には、そのメンバーが属するクラスのインスタンスを生成する必要があります。
エラーメッセージでは「静的でないメンバー ‘member’ にオブジェクト参照が必要です」と表示されるため、コードのどこでインスタンスの生成が省略されているのかがポイントとなります。
エラー発生のメカニズム
このエラーは、以下のような構文的ルールに基づいて発生します。
C#では、非静的メンバーはクラスの各インスタンスにひも付くため、以下の数式のように表せます。
つまり、静的メソッドのようなクラス全体に関わるメソッド内でインスタンスフィールドにアクセスする場合、必ず適切なオブジェクトインスタンスを介してアクセスしなければなりません。
インスタンスの生成が抜けていると、コンパイラはどのオブジェクトのメンバーか判断できなくなるため、エラーが発生します。
発生原因と代表的なケース
静的メソッド内での非静的メンバーアクセス
静的メソッド内で、インスタンス変数やインスタンスメソッドへ直接アクセスしようとするとエラーが発生します。
たとえば、以下のコードでは、Main
メソッドが静的であるため、同じクラス内の非静的なフィールドi
やメソッドMethod
を直接呼び出すとCS0120エラーが発生します。
インスタンス生成の省略によるエラー
インスタンスの生成を省略することも原因となります。
クラスのメンバーが静的でない場合、インスタンスを生成しなければそのメンバーにアクセスできないため、インスタンスによる明示的なアクセスが必要です。
ケーススタディ:複数事例の比較
以下のリストは、CS0120エラーが発生するパターンとその修正方法の代表的な事例です。
- パターン1: 静的メソッド内でそのまま非静的フィールドにアクセスする
・エラー例: i = 10;
・修正例: MyClass instance = new MyClass(); instance.i = 10;
- パターン2: 静的メソッド内で非静的メソッドを直接呼び出す
・エラー例: Method();
・修正例: MyClass instance = new MyClass(); instance.Method();
- パターン3: 非静的プロパティに対して直接アクセスを試みる
・エラー例: int p = Prop;
・修正例: MyClass instance = new MyClass(); int p = instance.Prop;
エラー解決手法
オブジェクトインスタンス生成による修正
CS0120エラーを解決するための基本的な方法は、非静的なメンバーにアクセスする前に、クラスのインスタンスを作成することです。
たとえば、以下のようにnew
演算子を用いてインスタンスを生成し、そのインスタンスを経由してメンバーにアクセスすることで、エラーを回避できます。
メンバーの静的化による対策
もう一つの解決策は、エラーの発生対象となっているメンバーを静的に定義する方法です。
メンバーが特定のインスタンスに依存せず、クラス全体で共有されるものである場合、静的化することでインスタンス生成の必要がなくなります。
修正時の注意点
- メンバーを静的に変更すると、クラスの各インスタンス間で共有された値になってしまうため、状態管理に注意が必要です。
- 静的メンバーはインスタンス固有の状態を持たないため、個別の状態を管理したい場合には適さないことを理解する必要があります。
- 既存コードとの整合性を保つため、静的化の選択は慎重に行いましょう。
コード例による具体的解説
非静的メンバーアクセス前のコード例
以下は、CS0120エラーが発生するサンプルコードです。
静的メソッドMain
内で、非静的なフィールドi
やメソッドMethod
に直接アクセスしようとしています。
using System;
public class MyClass
{
// 非静的フィールド
public int i;
// 非静的メソッド
public void Method()
{
// メッセージを表示する処理
Console.WriteLine("非静的メソッドが実行されました。");
}
// 非静的プロパティ
public int Prop
{
get
{
return 1;
}
}
public static void Main()
{
// インスタンスを生成せずに非静的メンバーへアクセス
i = 10; // CS0120エラーが発生します
Method(); // CS0120エラーが発生します
int p = Prop; // CS0120エラーが発生します
}
}
// コンパイルエラー CS0120: 静的でないフィールド、メソッド、またはプロパティ 'member' に対して、オブジェクト参照が必要です。
正しいコード例と修正手順
次に、インスタンスを生成して非静的メンバーに正しくアクセスする方法を示します。
以下のコードでは、new
演算子を使用してクラスのインスタンスmc
を作成し、そのインスタンスを用いてフィールド、メソッド、プロパティにアクセスしています。
using System;
public class MyClass
{
// 非静的フィールド
public int i;
// 非静的メソッド
public void Method()
{
// 修正されたメッセージを表示
Console.WriteLine("非静的メソッドが正しく呼び出されました。");
}
// 非静的プロパティ
public int Prop
{
get
{
return 1;
}
}
public static void Main()
{
// クラスのオブジェクトインスタンスを生成
MyClass mc = new MyClass();
mc.i = 10; // 正常にフィールドにアクセス
mc.Method(); // 正常にメソッドを呼び出し
int p = mc.Prop; // 正常にプロパティにアクセス
// 出力確認
Console.WriteLine("i の値: " + mc.i);
Console.WriteLine("Prop の値: " + p);
}
}
非静的メソッドが正しく呼び出されました。
i の値: 10
Prop の値: 1
コード実行時の動作確認ポイント
- コンパイルエラーが発生せず、正常にビルドできるか確認してください。
- 実行時に、フィールドに設定した値やメソッドの動作、プロパティの返り値が期待どおりであることをチェックしてください。
- コンソール上に「非静的メソッドが正しく呼び出されました。」、「i の値: 10」、「Prop の値: 1」が表示されるか確認することで、修正が正しく反映されていることを確認できます。
まとめ
この記事では、C#のCS0120エラーの概要や発生のメカニズム、静的メソッド内での非静的メンバーアクセスによるエラー発生の原因と代表的なケースを説明しています。
さらに、オブジェクトインスタンスの生成やメンバーの静的化など、エラーを解決する具体的な手法とその注意点について、実例と共に詳しく解説しています。