1. ホーム
  2. c#

[解決済み】C#で抽象的な静的メソッドを持つことができないのはなぜですか?

2022-04-14 02:33:43

質問

私は、これまで プロバイダ 抽象的な静的メソッドを持つ抽象的なクラスを持ちたいという興味深い状況に出くわしました。このトピックに関するいくつかの投稿を読んで、なんとなく理解できたのですが、明確な説明はあるのでしょうか?

どのように解決するのですか?

静的メソッドは インスタンス化 オブジェクトの参照がなくても利用可能です。

静的メソッドの呼び出しはオブジェクトの参照ではなくクラス名を通して行われ、呼び出すための中間言語(IL)コードは、必ずしも使用したクラス名ではなく、抽象メソッドを定義したクラス名を通して呼び出すことになるのです。

例を示そう。

以下のようなコードで。

public class A
{
    public static void Test()
    {
    }
}

public class B : A
{
}

B.Testを呼び出すと、こんな感じ。

class Program
{
    static void Main(string[] args)
    {
        B.Test();
    }
}

次に、Mainメソッド内の実際のコードは次のようになります。

.entrypoint
.maxstack 8
L0000: nop 
L0001: call void ConsoleApplication1.A::Test()
L0006: nop 
L0007: ret 

見ての通り、A.Test を定義したのは A クラスなので、呼び出し先は B.Test ではなく、そのようにコードを書くことができるにもかかわらず、A.Test になっています。

もし、あなたが クラスタイプ Delphiのように、オブジェクトではなく型を参照する変数を作ることができれば、仮想的な、つまり抽象的な静的メソッド(およびコンストラクタ)をもっと活用できるはずですが、これらは利用できず、したがって.NETでは静的呼び出しは非仮想的なものとなります。

IL設計者は、B.Testを呼び出すようにコードをコンパイルし、実行時に呼び出しを解決することを許可することはできますが、それでも、そこに何らかのクラス名を書かなければならないので、仮想にはなりませんね。

仮想メソッド、つまり抽象メソッドは、実行時にさまざまな種類のオブジェクトを格納できる変数を使用する場合にのみ有効で、その変数に格納されている現在のオブジェクトに適したメソッドを呼び出すことができます。静的メソッドでは、とにかくクラス名を調べる必要があり、そのため、呼び出すべき正確なメソッドはコンパイル時に分かっています。

このように、.NETでは仮想・抽象の静的メソッドは使用できません。