C #: любой способ подавить ошибки компилятора, аналогичные подавлению предупреждающих сообщений? - PullRequest
7 голосов
/ 15 февраля 2011

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

    Boolean IConvertible.ToBoolean(IFormatProvider provider)
    {
        ThrowHelper.ThrowInvalidCast(typeof(MyType), typeof(Boolean));
    }

Компилятор жалуется, что не все пути кода возвращают значение.Проблема здесь в том, что ThrowHelper ВСЕГДА выдаст ошибку.Это статический класс, вызывающий статический метод.

Я понимаю, что могу удовлетворить компилятор глупым «возвратом истины» после вызова ThrowHelper, но это кажется ненужным кодом.Я знаю, что могу подавить предупреждающие сообщения, но когда я попытался использовать SuppressMessageAttribute, это не помешает компилятору пожаловаться.Любой способ подавить эту ошибку только для этого метода?

Ответы [ 3 ]

8 голосов
/ 15 февраля 2011

Вы можете иметь метод в ThrowHelper только для создания исключения, но не для его выброса.

Boolean IConvertible.ToBoolean(IFormatProvider provider)
{
    throw ThrowHelper.CreateInvalidCast(typeof(MyType), typeof(Boolean));
}

Возможно, это также приведет к лучшей трассировке стека: оно будет указывать на ToBoolean, а не на ThrowInvalidCast.

6 голосов
/ 15 февраля 2011

Нет способа устранить ошибку, кроме как исправить ее.

Ошибка по своей природе указывает на то, что компилятор считает, что он не может сгенерировать допустимый код. Единственный способ подавить ошибки - это исправить их. Просто добавьте требуемый оператор return, а затем поднимите вопрос о Microsoft Connect , указывающий на то, что вы считаете, что компилятор ошибается в этом.

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

3 голосов
/ 15 февраля 2011

Простое упражнение для мозга, почему запрошенная функция может привести к проблемам. Представьте, что ThrowHelper.ThrowInvalidCast определено в какой-то сторонней библиотеке. Возможно, вы знаете, что метод всегда генерирует и сообщает об этом компилятору, или очень продвинутый статический анализатор может определить, что метод всегда генерирует в момент компиляции кода.

Теперь какой-то другой разработчик развертывает обновленную версию этой библиотеки. Теперь метод не всегда выбрасывает. Внезапно возникает ситуация, когда у вашего метода нет пути возврата. Просто для обработки этого случая компилятор (или среда выполнения) должен будет включить план резервного копирования, что делать в такой ситуации. Довольно много накладных расходов на то, что можно легко исправить, написав правильный код.

ОБНОВЛЕНИЕ: Теоретически, C # может быть расширен, чтобы позволить методы без пути возврата. Эрик Липперт упомянул это в комментарии к ответу Джона Скита здесь :

Метод "never" будет просто методом void, которому не разрешено иметь достижимую конечную точку или любые операторы возврата. Это решает проблему во время компиляции. Во время выполнения ответственность за обеспечение правильной реализации семантики возвращаемого типа лежит на верификаторе; верификатор мог бы также определить, что нет никаких инструкций возврата и что конечная точка недостижима.

...