CS0~400

C# コンパイラエラー CS0112 について解説:static キーワードと override の正しい使い方

CS0112 は C# のコンパイラエラーで、static 修飾子が付いたメソッドに対して overridevirtual、または abstract キーワードを同時に使用しようとすると発生します。

static メンバーはクラス全体で共有されるため、インスタンスごとに機能を上書きすることはできません。

コードを修正して、キーワードの使用方法を見直してください。

CS0112 エラーの発生原因

static 修飾子と override の競合

C# では、static 修飾子と override キーワードは同時に使用できません。

static 修飾子はクラス自体に属するメンバーを定義する際に使われ、override は継承したメソッドの動作を変更したいときに使います。

これらのキーワードは異なる目的で設計されているため、同時に用いられるとコンパイラが混乱し、エラー CS0112 が発生します。

例えば、基底クラスに定義された abstract または virtualメソッドは、インスタンスに対して動作させるものであるため、静的なメンバーとして定義することはできません。

コンパイラによる検出の仕組み

コンパイラはソースコードを解析する際に、クラス宣言やメソッド宣言の各属性を確認します。

static 修飾子が付与されたメソッドに対して override キーワードが併記されている場合、コンパイラは以下のように動作します。

  • まず、メソッドが静的メンバーとして定義されているか確認
  • 次に、メソッド宣言に override キーワードが含まれているかを確認
  • 両方の条件が満たされると、キーワードの組み合わせが不正であると判断し、エラー CS0112 を発生させます

この仕組みにより、静的メンバーは継承によるオーバーライドの対象外であることが強制されます。

コード例によるエラー再現

再現コードの解説

以下のコード例では、staticoverride を同時に適用しており、コンパイラがエラーを検出します。

コード内では、基底クラス MyClassabstractメソッド 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 として定義することはできません。

エラー箇所の特定方法

エラー箇所はコンパイルエラーのメッセージによって示されます。

具体的には、以下の手順で特定できます。

  • コンパイルエラーの内容を確認し、エラーメッセージに示されているキーワード staticoverride を探す
  • オーバーライドするメソッドが静的メンバーとして定義されているかを再度確認する
  • ソースファイル内で該当部分のコードブロックをチェックする

上記の方法により、どの行で不正なキーワードの組み合わせが行われているかを容易に特定することが可能です。

修正方法の解説

正しいキーワードの組み合わせ

エラー 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 エラーの原因が staticoverride の不適切な組み合わせに起因する点を解説しています。

コンパイラがどのようにエラーを検出するかや、実際のコード例を通じてエラー発生箇所の特定方法を説明しています。

また、正しいキーワードの組み合わせを用いた修正方法として、修正前と修正後のコード例を示し、同様のケースとの対比や静的メンバー使用時の注意点も紹介しています。

関連記事

Back to top button
目次へ