Вопрос о неоднозначных звонках в C # - PullRequest
9 голосов
/ 20 мая 2009

У меня есть вопрос, который на самом деле не проблема, но что-то, что сделало меня немного любопытным.

У меня есть класс с двумя методами. Один является статическим методом, а другой - методом экземпляра. Методы имеют одинаковое имя.

public class BlockHeader
{
    public static BlockHeader Peek(BinaryReader reader)
    {
        // Create a block header and peek at it.           
        BlockHeader blockHeader = new BlockHeader();
        blockHeader.Peek(reader);
        return blockHeader;
    }

    public virtual void Peek(BinaryReader reader)
    {
        // Do magic.
    }
}

Когда я пытаюсь построить свой проект, я получаю сообщение об ошибке:

Звонок между следующие методы или свойства: 'MyApp.BlockHeader.Peek (System.IO.BinaryReader)' а также 'MyApp.BlockHeader.Peek (System.IO.BinaryReader)'

Я знаю, что сигнатуры метода практически одинаковы, но я не понимаю, как я мог бы вызвать статический метод непосредственно из члена экземпляра.

Я предполагаю, что для этого есть очень веская причина, но кто-нибудь знает, что это за причина?

Ответы [ 3 ]

9 голосов
/ 20 мая 2009

Общая политика дизайна C # состоит в том, чтобы заставить вас указывать, где есть потенциальная неопределенность. Перед лицом инструментов рефакторинга, которые позволяют заново настроить, статичны ли вещи или нет, эта позиция великолепна, особенно в таких случаях. Вы увидите много других подобных случаев (переопределение по сравнению с виртуальным, новое для теневого копирования и т. Д.).

Как правило, удаление этого типа комнаты для путаницы сделает код более понятным и заставит вас поддерживать порядок в вашем доме.

РЕДАКТИРОВАТЬ: Хороший пост от Эрика Липперта обсуждает еще одну причину этой двусмысленности, ведущей к ошибке, которую вы видели

4 голосов
/ 20 мая 2009

Вот выдержка из спецификации языка C # 3.0.

Подпись метода должна быть уникальной в классе, в котором объявлен метод. Сигнатура метода состоит из имени метода, количества параметров типа и числа, модификаторов и типов его параметров. Сигнатура метода не включает тип возвращаемого значения.

Модификатор «static» не является частью подписи, поэтому ваш пример нарушает это правило уникальных подписей.

Хотя я не знаю причину этого правила.

2 голосов
/ 20 мая 2009

Я думаю, что нет технической причины, чтобы это запретить, но это сделано для защиты программиста от самого себя. Рассмотрим следующий пример:

public static void Main()
{
  BlockHeader BlockHeader = new BlockHeader();
  BlockHeader.Peek();
}

Приведенный выше пример совершенно верен, но если бы описанная вами ситуация была разрешена, она была бы удобочитаемой? Не могли бы вы в мгновение ока увидеть, был ли вызван метод экземпляра или статический метод?

...