StackOverflowException в перегруженных методах - PullRequest
2 голосов
/ 05 июля 2011

Я пытаюсь вызвать перегруженный метод в коде так:

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(ChildClass other).

вызывается Method(BaseClass<ChildClass> other).

Но когда я использую приведение:

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

все работает как положено. Я что-то пропустил? Или это ошибка в .NET? Протестировано в .NET 2.0,3.5,4.0

1 Ответ

2 голосов
/ 05 июля 2011

Раздел 7.3 спецификации C # гласит:

Сначала набор всего доступного (Раздел 3.5) Члены с именем N объявлены в T и базовых типах (раздел 7.3.1) T построено. Объявления, которые включают переопределение модификатор исключен из набора. Если члены с именем N не существуют и не являются доступно, то поиск производит нет совпадения, и следующие шаги не оценивается.

Поскольку оба метода применимы, но один из них помечен как переопределенный, он игнорируется для определения того, какой метод вызывать. Таким образом, текущий метод вызывается, что приводит к вашей рекурсии. Когда вы выполняете приведение, переопределенная версия является единственным применимым методом, и поэтому вы получаете желаемое поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...