C# コンパイラエラー CS0112 について解説:static キーワードと override の正しい使い方
CS0112 は C# のコンパイラエラーで、static
修飾子が付いたメソッドに対して override
、virtual
、または abstract
キーワードを同時に使用しようとすると発生します。
static メンバーはクラス全体で共有されるため、インスタンスごとに機能を上書きすることはできません。
コードを修正して、キーワードの使用方法を見直してください。
CS0112 エラーの発生原因
static 修飾子と override の競合
C# では、static
修飾子と override
キーワードは同時に使用できません。
static
修飾子はクラス自体に属するメンバーを定義する際に使われ、override
は継承したメソッドの動作を変更したいときに使います。
これらのキーワードは異なる目的で設計されているため、同時に用いられるとコンパイラが混乱し、エラー CS0112 が発生します。
例えば、基底クラスに定義された abstract
または virtual
メソッドは、インスタンスに対して動作させるものであるため、静的なメンバーとして定義することはできません。
コンパイラによる検出の仕組み
コンパイラはソースコードを解析する際に、クラス宣言やメソッド宣言の各属性を確認します。
static
修飾子が付与されたメソッドに対して override
キーワードが併記されている場合、コンパイラは以下のように動作します。
- まず、メソッドが静的メンバーとして定義されているか確認
- 次に、メソッド宣言に
override
キーワードが含まれているかを確認 - 両方の条件が満たされると、キーワードの組み合わせが不正であると判断し、エラー CS0112 を発生させます
この仕組みにより、静的メンバーは継承によるオーバーライドの対象外であることが強制されます。
コード例によるエラー再現
再現コードの解説
以下のコード例では、static
と override
を同時に適用しており、コンパイラがエラーを検出します。
コード内では、基底クラス MyClass
の abstract
メソッド Foo
を、派生クラス MyClass2
でオーバーライドしながら static
修飾子を付けています。
この組み合わせによりエラーが発生します。
// CS0112_ErrorDemo.cs
namespace SampleNamespace
{
// 基底クラス、抽象メソッド Foo を宣言
abstract public class MyClass
{
public abstract void Foo();
}
// 派生クラス、Foo をオーバーライドしつつ static を誤って付与
public class MyClass2 : MyClass
{
// CS0112 エラーが発生する箇所
override public static void Foo() // エラー: 静的メンバーに対して override は使用できません
{
// サンプル用のメッセージを出力
System.Console.WriteLine("This is an incorrect override with static keyword.");
}
public static int Main()
{
// エラーが発生するため本来このコードは実行されません
return 0;
}
}
}
// コンパイル時に以下のようなエラーメッセージが表示される
// error CS0112: 静的メンバー 'MyClass2.Foo()' を override、virtual、または abstract として定義することはできません。
エラー箇所の特定方法
エラー箇所はコンパイルエラーのメッセージによって示されます。
具体的には、以下の手順で特定できます。
- コンパイルエラーの内容を確認し、エラーメッセージに示されているキーワード
static
やoverride
を探す - オーバーライドするメソッドが静的メンバーとして定義されているかを再度確認する
- ソースファイル内で該当部分のコードブロックをチェックする
上記の方法により、どの行で不正なキーワードの組み合わせが行われているかを容易に特定することが可能です。
修正方法の解説
正しいキーワードの組み合わせ
エラー CS0112 を回避するには、static
修飾子と override
キーワードを同時に使用しないようにコードを変更する必要があります。
通常は、基底クラスのメソッドがインスタンスメンバーとして定義されているため、派生クラスでオーバーライドする際もインスタンスメソッドとして定義することで対応します。
修正前のコード例
以下のコード例は不正なキーワードの組み合わせによりエラーを発生させます。
namespace FixedNamespace
{
abstract public class MyClass
{
public abstract void Foo();
}
public class MyClass2 : MyClass
{
// 修正前: static キーワードと override キーワードを同時に使用しているためエラー
override public static void Foo()
{
System.Console.WriteLine("Incorrect usage of static with override.");
}
public static int Main()
{
return 0;
}
}
}
// エラーメッセージ: CS0112: 静的メンバー 'MyClass2.Foo()' を override、virtual、または abstract として定義することはできません。
修正後のコード例
修正後は、override
キーワードのみを使用し、インスタンスメソッドとして定義します。
namespace FixedNamespace
{
abstract public class MyClass
{
public abstract void Foo();
}
public class MyClass2 : MyClass
{
// 修正後: static キーワードを削除し、正しい形でオーバーライドを実施
override public void Foo()
{
System.Console.WriteLine("Correct override without static keyword.");
}
public static int Main()
{
// インスタンス生成後、Foo メソッドの実行結果を確認
MyClass myClassInstance = new MyClass2();
myClassInstance.Foo();
return 0;
}
}
}
// 出力結果:
// Correct override without static keyword.
注意事項
similar ケースとの対比
他のケースでも、キーワードの誤用によってエラーが発生することがあります。
例えば、virtual
キーワードと abstract
キーワードを同時に使用する場合もエラーとなるため、各キーワードの意味と適用範囲を正しく理解することが大切です。
基本的に、メソッドをオーバーライドする場合は、基底クラスで abstract
もしくは virtual
として宣言されている必要があり、static
キーワードは使用しません。
static と override 使用時の留意点
static
修飾子はクラスレベルのメンバーを定義するために使用され、インスタンスの生成を必要としません。
そのため、インスタンスに依存する override
を行う際には適用できません。
静的メンバーとしてメソッドを使用したい場合は、継承やオーバーライドの仕組みとは無関係にデザインする必要があります。
また、もし継承関係にあるクラスで同じ名前の静的メソッドを実装する場合は、new
キーワードを使用して隠蔽する方法もありますが、これはオーバーライドとは異なる動作となります。
まとめ
この記事では、CS0112 エラーの原因が static
と override
の不適切な組み合わせに起因する点を解説しています。
コンパイラがどのようにエラーを検出するかや、実際のコード例を通じてエラー発生箇所の特定方法を説明しています。
また、正しいキーワードの組み合わせを用いた修正方法として、修正前と修正後のコード例を示し、同様のケースとの対比や静的メンバー使用時の注意点も紹介しています。