2

次のようなコードでオーバーロードされたメソッドを呼び出そうとしています:

public abstract class BaseClass<T>
{
    public abstract bool Method(T other);
}

public class ChildClass : BaseClass<ChildClass>
{
    public bool Method(BaseClass<ChildClass> other)
    {
        return this.Method(other as ChildClass);
    }

    public override bool Method(ChildClass other)
    {
        return this == other;
    }
}

class Program
{
    static void Main(string[] args)
    {
        BaseClass<ChildClass> baseObject = new ChildClass();
        ChildClass childObject = new ChildClass();

        bool result = childObject.Method(baseObject);
        Console.WriteLine(result.ToString());
        Console.Read();
    }
}

すべて問題ないように見えますが、StackOverflowException がスローされます。私の理解では、オーバーロードされたメソッドを呼び出す場合、最も具体的なメソッド バージョンを呼び出す必要がありますが、この場合は のMethod(BaseClass<ChildClass> other)代わりに が呼び出されMethod(ChildClass other)ます。

しかし、キャストを使用する場合:

return ((BaseClass<ChildClass>)this).Method(other as ChildClass);

すべてが期待どおりに機能します。私は何かが欠けていますか?または、これは .NET のバグですか? .NET 2.0、3.5、4.0 でテスト済み

4

1 に答える 1

2

C# 仕様のセクション 7.3 には次のように記載されています。

最初に、T で宣言された N という名前のすべてのアクセス可能な (セクション 3.5) メンバーのセットと、T の基本型 (セクション 7.3.1) が構築されます。オーバーライド修飾子を含む宣言はセットから除外されます。N という名前のメンバーが存在せず、アクセス可能である場合、ルックアップは一致を生成せず、次の手順は評価されません。

両方のメソッドが適用可能ですが、そのうちの 1 つがオーバーライドとしてマークされているため、どちらのメソッドを呼び出すかを決定する目的では無視されます。したがって、現在のメソッドが呼び出され、再帰が発生します。キャストを行うと、オーバーライドされたバージョンが唯一の適用可能なメソッドになるため、目的の動作が得られます。

于 2011-07-05T14:33:26.117 に答える