Почему операторы, которые ничего не делают, не вызывают исключения (или не предупреждают разработчика)?

StackOverflow https://stackoverflow.com/questions/1772326

Вопрос

Пару раз меня укусили операторы в VB.NET (не уверен, существует ли этот эффект в C#), которые кажутся самоссылающимися, но когда они выполняются, они фактически ничего не делают, потому что требуют цель, а она не указана.Например:

Dim MyString as string = "String to test"

' Neither of these lines do anything '
MyString.Replace(" ", "-")
MyString.Substring(0,5)

' This will return the original string, because neither statement did anything '
Messagebox.Show(MyString)

В обоих случаях .NET, похоже, не беспокоит то, что оператору нужна цель, которой можно присвоить результат, а я ее не даю.Есть ли причина, по которой IDE/компилятор не предупреждает меня об этом эффекте или что не создается исключение «StatementDoesntDoAnything»?Поскольку код сформирован таким образом, что он никогда ничего не изменит, то он явно опечатался.

Это было полезно?

Решение

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

Функции, которые «просто» возвращают значения, должны быть помечены как таковые, чтобы компилятор их проверял, и это просто не было приоритетом или оценивалось как достаточное окупаемость инвестиций (очевидно, иначе они бы это сделали :) .

Другие советы

Да, было бы здорово, если бы методы, не имеющие побочных эффектов, можно было помечать каким-нибудь [NoSideEffectsAttribute()], чтобы такие инструменты, как компиляторы, могли вас предупреждать, но в настоящее время мне ничего подобного не известно.

Но вы можете попробовать FxCop, он может обнаружить множество тонких ошибок программирования в сборках .NET.

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

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

Компилятору часто бывает сложно определить, «делают ли» функции что-то.Если компилятор не примет строгие меры Межпроцедурный анализ (IPA), он не может определить, имеет ли вызов функции побочный эффект.

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

Это унаследованное поведение от C, C++, и изначально оно было сделано для того, чтобы вы могли выбирать, использовать или нет возвращаемое значение из функции/метода...Когда вы пишете функцию/метод, которая выполняет кучу действий, а затем возвращает какое-то значение, при ее вызове у вас есть возможность написать

variableName = functionName([parameterlist]);  

если вы хотите использовать значение returnb в чем-то или просто

functionName([parameterlist]);  

если вы этого не сделаете.

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

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

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

2) Предположим, вы делаете обратное, добавляя ключевое слово при принудительном возвращаемом значении. Некоторые люди просто используют фиктивные переменные для их хранения и продолжают использовать их так, как раньше.

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

Рассмотрим метод Dictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value):он проверяет, есть ли ключ в словаре, и если да, то помещает значение в словарь. out параметр.Возвращаемое значение представляет собой bool указывающий, была ли операция успешной.Иногда вам не все равно;иногда нет.Я думаю, что это вполне приемлемый подход для подобных методов;если бы компилятор заставил вас присвоить возвращаемое значение переменной, у людей было бы много такого кода:

int someValue = 0;
bool discard = IntDictionary.TryGetValue("key", out someValue);

// I don't even care if discard is true or false;
// someValue will be 0 if it wasn't in IntDictionary

меня пару раз укусил

поспешные выводы, а не

операторы в VB.NET...что ...на самом деле ничего не делай

но на самом деле это очень хорошо документировано.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top