это излишество для оценки Main(string[] args)

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

static void Main(string[] args) {
    if (args.Length == 0 || args == null) {           
        //do X
    }
    else { 
        //do Y 
    }
}

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


person whytheq    schedule 19.03.2012    source источник
comment
Ваша логика неверна. Что произойдет, если args будет null? Проверка args.Length вызовет NullReferenceExcetpion   -  person Greg B    schedule 19.03.2012
comment
перебор? не совсем. если вам абсолютно не нужно предоставлять ответ, когда для выполнения программы требуются аргументы, сделайте это. Грег Б прав, проверьте значение null, затем проверьте длину.   -  person Martin Ongtangco    schedule 19.03.2012
comment
Как правило, вы должны проверять значение null перед чем-либо еще, потому что, если args действительно равно нулю, ваше первое условие выдаст NullReferenceException.   -  person Ioannis Karadimas    schedule 19.03.2012


Ответы (5)


Ну, Main определено так, чтобы никогда не вызываться с параметром null. Если он действительно каким-то образом получает нулевой параметр, то ваша среда настолько нарушена, что все ставки сняты, независимо от того, что вы делаете, поэтому на самом деле ничего не получится, проверив null.

С другой стороны, если вы делаете проверку на null, то читатели и сопровождающие код должны будут понять, почему. Почему первоначальный программист поставил такую ​​бесполезную проверку? Он знал что-то, чего не знаем мы? Мы не можем просто удалить его, потому что он мог обнаружить какую-то странную ошибку!

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

Однако в ситуациях, когда такая проверка нуля имеет смысл, она должна быть крайним левым условием.

В таком тесте: args.Length == 0 || args == null, args.Length оцениваются сначала, и если это не удается, args сравнивается с null. Другими словами, если args равно null, ваш код выдаст исключение. Должно быть args == null || args.Length == 0

person jalf    schedule 19.03.2012
comment
Это действительно ужасный ответ. Все хорошие разработчики знают, что нельзя полагаться на поведение внешнего кода, когда он вызывает их общедоступные функции. Защитное программирование всегда превосходит программирование с надеждой (т. е. надежда на то, что параметр не равен нулю). Это действительно плохая практика - привыкать принимать значения параметров. Проверьте на ноль - в этом нет ничего плохого, вы не можете утверждать, что в данном случае это удар по производительности, и это показывает, что вы думаете обо всех возможностях. - person adelphus; 19.03.2012
comment
Я ничего не говорил о производительности. Но, пожалуйста, скажите мне, насколько плохо полагаться на свой язык программирования и его библиотеку классов для того, чтобы делать то, что он говорит? Если вы не можете положиться на это, как вы можете писать какой-либо код? Если вы не можете этому доверять, то каждая написанная вами строка, включая проверку на нулевое значение, является подозрительной и ненадежной. Если вы хотите говорить об ужасных практиках, то это бессмысленное запутывание. Говорите, что, если все в целом мире коррумпировано и ненадежно? Что мы будем делать тогда? Я знаю, проверка на arg == null все исправит. Нет, не будет. - person jalf; 19.03.2012
comment
Если ваш мир сломан, то вы не можете его починить, и можете даже не пытаться. Вы можете называть это программированием надежды, если вам от этого станет лучше, но это единственное, что мы можем сделать. Мы должны надеяться, что компилятор сгенерирует код, который мы просили. Мы должны надеяться, что класс List<T> на самом деле хранит список T, мы должны надеяться, что Main будет вызываться при запуске. Мы должны надеяться, что доступ к объекту null вызовет ошибку NullReferenceException. Защитное программирование не может защитить вас от некорректной языковой реализации. - person jalf; 19.03.2012
comment
Кто сказал, что единственным вызывающим абонентом является .NET Framework? Это не имеет ничего общего с реализацией языка — все дело в хорошей практике программирования. Этот вопрос легко можно задать о любом другом языке. Защитное программирование заключается в том, чтобы убедиться, что поведение программы известно и хорошо понято в случае ошибок. Если вы этого не сделаете и будете полагать, что все будет хорошо, вас ждет целый мир боли, когда все рухнет. - person adelphus; 19.03.2012
comment
Если бы я ехал на велосипеде, зачем мне было бы носить мотоциклетный шлем - на случай, если однажды в будущем из велосипеда вырастет двигатель. Конечно, достаточно носить велосипедную шляпу, как говорит Ялф, если кто-то получит велосипед в будущем с мотоциклетным шлемом, они будут удивляться, что происходит! (может быть, не лучшая аналогия, которую я придумал) - person whytheq; 19.03.2012
comment
Из простого вопроса родилась интересная дискуссия... :) - person Tigran; 19.03.2012
comment
@whytheq Я бы сказал, что вы вообще не носите шлем :-) Все говорили вам, что ни одна машина никогда не выедет перед вами, так что вы думаете, что все в порядке. Проблема в том, что я видел, как множество автомобилей сгоняют множество велосипедов (метафорически говоря). Лично я не хочу умирать, и я не хочу, чтобы кто-то, кто использует мой велосипед, умер. - person adelphus; 19.03.2012
comment
@adelphus: Тогда вы можете обязать любого гонщика носить защитный костюм толщиной 10 футов и парашют, а также нести ядерную ракету на случай падения астероидов. Признайтесь, вы не можете - и не должны! - защитить от всех странных вещей, которые могут когда-либо случиться. Учтите (чтобы вернуться к теме :)), что если что-то вызывает Main(null), что-то фундаментально сломано. Это что-то будет вызывающим, и именно здесь должно быть исправление. if (args == null) это пластырь на сломанной ноге. - person cHao; 19.03.2012
comment
как-то уж слишком все это сюрреалистично - это серьезный сайт для серьезного анализа... в следующий раз лучше оставьте мои дешевые аналогии при себе - person whytheq; 19.03.2012
comment
+1, за 11 комментариев, длинная дискуссия-аргумент-дебаты. - person ApprenticeHacker; 20.03.2012
comment
@adelphus: этот вопрос можно легко задать о любом другом языке. Серьезно? Значит, защитное программирование — это защита от случаев, когда ваш код вдруг оказывается на другом языке? Я могу только представить это. О дерьмо, код C++, который я писал последние 8 месяцев, только что оказался Прологом! Черт, если бы я только защитился от вызова main с неверными параметрами. Этот вопрос касается метода Main на одном конкретном языке. На этом языке Main вызывается один раз во время выполнения при запуске приложения, если только программист не сошел с ума. - person jalf; 20.03.2012
comment
и если программист сошел с ума, нулевая проверка нам не поможет. - person jalf; 20.03.2012
comment
@whytheq: Если бы я ехал на велосипеде, зачем мне было бы носить мотоциклетный шлем - на случай, если однажды в будущем у велосипеда вырастет двигатель - это отличная аналогия. Рассмешило меня. +1 :) - person jalf; 20.03.2012
comment
Я признаю, что проиграл эту битву с Ней. @jalf, вы явно не понимаете, что такое защитное программирование и почему оно используется. Я признаю, что в этом конкретном случае существует высокая вероятность того, что параметр не будет нулевым. Тем не менее, я рассматриваю SO как учебный форум, а также как QA, и надеюсь, что я, по крайней мере, дал другим читателям пищу для размышлений. - person adelphus; 20.03.2012
comment
@adelphus: я знаю, что такое защитное программирование. Но ОП задал конкретный вопрос о проверке нулевого значения в очень конкретном сценарии. Я абсолютно с вами согласен, во многих других случаях имеет смысл проверять значение null. Но мы не о тех случаях. Мы говорим о программе C#, в которой метод Main проверяет, равен ли его аргумент null. SO — это учебный форум, и один из важных уроков, который должен усвоить каждый программист, заключается в том, что это зависит. Слепая проверка всего на значение null так же глупо, как проверка ничего. - person jalf; 20.03.2012
comment
if(аргумент == обсуждение) { GiveUp();} - person whytheq; 20.03.2012
comment
один из лучших ответов на SO - person vidstige; 12.10.2012
comment
@jalf, просто чтобы уточнить, ни одно из значений argss не может быть нулевым, верно? (конечно, при условии, что это вызывает среда выполнения, а не какой-то сумасшедший программист) - person Ohad Schneider; 22.07.2017

В соответствии с этим вам нужно только Проверьте :

if (args.Length == 0)
{
    // Do X
}

Хотя проверка на null не приносит никакого вреда, в этом нет реальной необходимости.

person ApprenticeHacker    schedule 19.03.2012
comment
+1 за бритву Оккама и предоставление ссылки. Остальные ответы верны, конечно, для общих случаев, но этот вопрос был очень специфичен. - person Mr Lister; 19.03.2012
comment
@InternediateHacker - хороший; Я думал, что вспомнил, что есть запись msdn, но не смог ее найти! - person whytheq; 19.03.2012

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

И еще: сначала проверяйте на null, потом на Length

person Tigran    schedule 19.03.2012
comment
Да, это абсолютно плохая идея — добавлять бесполезный код. Это загромождает код, затрудняет его чтение и понимание и, проще говоря, дает вам больше кода для сопровождения. Main не вызывается с нулевым параметром, поэтому не усложняйте свой код, пытаясь проверить что, если это произойдет - person jalf; 19.03.2012
comment
Ну, ваш метод Main обычно не должен использоваться более одного раза за выполнение программы ;-) - person Péter Török; 19.03.2012
comment
@jalf: до сих пор я никогда не использовал программу, в которой метод Main используется более одного раза, не знаю, использовали ли вы. Мысль состоит в том, что если предположим, что в один прекрасный день после некоторого пакета обновлений (обновления) он может стать нулевым, ваша программа не выйдет из строя. Просто добавьте дополнительный контроль и живите счастливо. Простой. - person Tigran; 19.03.2012
comment
@Tigran: пакеты обновления не изменяют спецификацию языка, чтобы сломать существующие программы. И если это так, то для исправления вашей программы требуется нечто большее, чем проверка нуля. Если бы такой пакет обновлений был выпущен, он сломал бы гораздо больше, чем это. Но представьте, что вы не написали этот код, а прочитали его. Представьте, что вам нужно было его поддерживать. Моя реакция при чтении была бы такой: какого черта? Зачем нужна эта нулевая проверка? Знает ли оригинальный автор что-то, чего не знаю я? - person jalf; 19.03.2012
comment
А затем я тратил остаток дня, пытаясь обнаружить ту ошибку, от которой он, очевидно, защищал, и исследовать случаи, когда args мог быть нулевым. Время потрачено впустую, потому что кто-то добавил в его код ненужную сложность. Если платформа .NET не соответствует своей собственной спецификации, мы облажались, что бы мы ни делали. Бесполезно писать свой код, предполагая, что .NET вам лжет. - person jalf; 19.03.2012
comment
@Tigran: Однажды, после некоторого пакета обновления, Console.WriteLine может вызвать появление единорогов и отформатировать ваш жесткий диск. Вы не можете и не должны защищаться от каждого случая, который может произойти в будущем - учтите, что если бы были внесены такие критические изменения, у вас было бы гораздо больше поводов для беспокойства, чем args нулевое значение. - person cHao; 19.03.2012
comment
@cHao: можно поточнее? На самом деле неясно, будет ли это пакет обновлений или единороги форматировать ваш жесткий диск. Я просто хочу убедиться. ;) - person jalf; 19.03.2012
comment
@jalf: не уверен. Я вижу корреляцию между появлением единорогов и загадочным форматированием жестких дисков. Однако нельзя сказать наверняка, что это делают единороги. - person cHao; 19.03.2012
comment
@jalf: понял вашу мысль, но вы не можете убедить меня, что наличие в коде одной проверки нулевой ссылки сделает его менее читаемым, создаст вам путаницу и заставит терять время на изучение ( ???) код, который вы смотрите. - person Tigran; 19.03.2012
comment
Возможно, я не могу. Но если нет, то вам не нужно было поддерживать много кода. Простота важна. Понимание, почему код выглядит так, чрезвычайно важно. Если вы не можете объяснить, почему ваш код выглядит так, как он хочет, я не хочу его поддерживать. - person jalf; 19.03.2012
comment
@jalf: согласен с этим +1. К сожалению, поддержание старого (унаследованного) кода является частью моей работы, так что поделитесь своими мыслями. - person Tigran; 19.03.2012
comment
Извините, ребята, но все те, кто считает, что не стоит защищаться от всех случаев, просто плохие разработчики. Я встречал ооочень много случаев, когда разработчик реагировал на сбой программы словами: Ну, параметр никогда не должен иметь такого значения, в которое он не верится. Полагаться на чужие слова о том, что значения параметров публичных функций будут содержать только определенные значения, является фатальной ошибкой. - person adelphus; 19.03.2012
comment
@adelfus: согласен. Не нравится, что я знаю, что делаю, и после получения звонков в полночь от какого-то клиента с проблемой, что программа дала сбой, и он потерял все свои данные. Потому что точно этот сценарий, к сожалению, случается много время в моей жизни. Желательно иметь проверку, журнал и уведомление пользователя о сбое операции. Таким образом, клиент ничего не теряет (даже если он не может закончить свою работу, но это лучше). - person Tigran; 19.03.2012
comment
@adelphus: Есть разница между тем, что не должно быть, и не будет, или даже не может быть. В этом случае args никогда не будет нулевым (за одним исключением... если кто-то специально вызывает его в приложении и передает null). Это не библиотечная функция; это часть спецификации самой CLR. Дело не только в том, что этого не должно происходить; этого не произойдет, если вы не вызовете Main (неправильно!) из своего приложения... или что-то пошло не так, что вы не можете доверять среде выполнения. И если вы не можете доверять среде выполнения даже для правильного запуска вашего приложения, как вы можете доверять чему-либо с этого момента? - person cHao; 19.03.2012
comment
Мне нравится, когда люди говорят, что ‹x› никогда не случится… кроме случаев ‹y›. Мне это так нравится, что я часто обнимаю разработчика, когда случается ‹y›, и кто-то должен убрать остатки. - person adelphus; 19.03.2012
comment
@adelphus: есть ровно один случай, когда это ‹y› произойдет. И в этом случае все, что вызывается Main(null), сломано. Период. Когда правила игры установлены, а вы отказываетесь по ним играть, все ставки снимаются. В этом случае правила устанавливаются самой CLR. Когда они сломаны, код должен сломаться. Радостно. И тот, кто добавляет if (args == null) { /* oh noes */ } в свой код, вместо того, чтобы исправить звонящего (который находится в том же чертовом приложении), должен быть повешен за свою некомпетентность. - person cHao; 19.03.2012
comment
@adelphus: ты упускаешь суть. Дело не в том, что ‹x› никогда не произойдет, а в том, что если ‹x› произойдет, мы облажались, несмотря ни на что, и то, что вы предлагаете, не исправит программу, если ‹x› произойдет. Знаете, что я люблю? Мне нравится, когда программисты говорят, что ‹x› обычно никогда не происходит, и если это произойдет, мы ничего не сможем исправить, так что знаете, что я сделаю? Я напишу много кода, который попытается восстановить в любом случае - person jalf; 20.03.2012
comment
Мне это так нравится, что я часто обнимаю разработчика, когда происходит ‹x› и кто-то должен не просто исправить ошибку, но и также пробиться сквозь эти слои и слои запутанного бесполезного< /i> код, который не служит никакой цели, кроме как скрыть возникшую ошибку, которую еще нужно исправить - person jalf; 20.03.2012
comment
@Tigran: какой сценарий чаще всего случается в твоей жизни? Что CLR ломается таким образом, что защитные методы кодирования могут спасти положение и избежать полуночных звонков от клиента? я нахожу это маловероятным - person jalf; 20.03.2012
comment
@jalf: нет :) Надеюсь, не CLR. Часто бывает, что разработчик предполагает: этого никогда не случится, а в 90% произойдет. Я говорю о не этом конкретном случае, по которому был задан вопрос. Наше обсуждение ушло далеко от актуальной темы вопроса. - person Tigran; 20.03.2012
comment
@jalf Я действительно надеюсь, что когда платящий клиент свяжется с вами, вы ответите: «Мое программное обеспечение преднамеренно дает сбой, потому что я хочу, чтобы оно делало это, когда что-то не так». - person adelphus; 20.03.2012
comment
@Tigran: ну, некоторые из нас пытаются ответить на вопрос ОП. ОП вообще не спрашивал о защитном программировании. Он не спросил о том случае на прошлой неделе, когда ваш клиент разозлился на вас за то, что вы не проверили, был ли какой-то параметр нулевым. Он спросил, не стоит ли проверить аргумент метода Main C# на соответствие null. - person jalf; 20.03.2012
comment
@jalf: существуют разные реальные миры программного обеспечения. Не у всех есть хорошие тестировщики (если есть), хорошие разработчики или хорошие менеджеры. Smeone работает напрямую с клиентами (в этом есть свои плюсы и минусы для разработчика ПО). Этот необычный способ программирования обычно используется теми, кто тесно работает с клиентом (клиентами). Другие, кто работает в офисе, в тишине и отделении от внешнего мира с организованным обслуживанием клиентов, могут и будут выбирать другие пути. Я думаю, это просто бизнес. - person Tigran; 20.03.2012
comment
@Тигран Абсолютно. Я бы сказал, что это больше похоже на 95%. Еще лучше, когда разработчик говорит: я на 100%/110%/1000% уверен, что этого никогда не произойдет. И тогда, конечно, это происходит. Оказывается, в данном случае важен опыт. - person adelphus; 20.03.2012
comment
@adelphus: я действительно надеюсь, что вы не берете деньги за программное обеспечение, которое пытается замаскировать ошибки и просто продолжает работать в ненадежном состоянии, где оно может нанести гораздо больший ущерб, чем если бы оно просто упало. Видишь, я тоже так могу. Может быть, мы могли бы придерживаться темы в течение пяти минут? - person jalf; 20.03.2012
comment
@adelphus: и все же я только что спросил, случалась ли проблема, о которой мы говорим, о защите от которой мы говорим, когда-либо, и он сказал, что нет. А ты? Случилось ли это для вас? И если бы это было так, можете ли вы серьезно, честно сказать, что этот нулевой чек спас бы положение? Дай мне попробовать снова. Я не говорю, что уверен, что этот параметр никогда не будет нулевым. Я говорю, что уверен, что если этот параметр когда-либо будет нулевым, то моя среда настолько испорчена, что все, что я могу сделать, не будет иметь значения. - person jalf; 20.03.2012
comment
Лично я голосую за закрытие этого вопроса по той причине, что это может вызвать ненужный эмоциональный стресс :-) - person adelphus; 20.03.2012
comment
Если Main вызывается с нулевым аргументом, у меня нет оснований полагать, что мой код вообще будет выполнен корректно. И поэтому, даже если бы я вставил эту нулевую проверку, я даже не могу быть уверен, что она будет выполнена или что она не сделает что-то еще, например, отформатирует жесткий диск клиента. Вы также можете написать код, чтобы убедиться, что ваш компилятор выдал правильный код или что ЦП исправен. Это явные ошибки, которые мы хотели бы поймать, но не можем, потому что, если они произойдут, ни на один наш код нельзя будет положиться. Так же, как мы не можем полагаться на наш код, если CLR внезапно сломается. - person jalf; 20.03.2012
comment
Проблема в @jalf, разработчики берут ваши рассуждения и применяют их в других местах. Все, что я пытаюсь сделать, это указать, что хорошие методы программирования включают в себя хорошую проверку параметров, в том числе проверку на нуль. Разработчик может легко просмотреть ваши комментарии и сказать: «Хорошо, в моем API этот целочисленный параметр никогда не будет больше 3, потому что в моей функции это не имеет смысла». Поэтому я не буду проверять этот случай. Это плохая практика, и она действительно вызывает проблемы. Последний комментарий в теме (обещаю). - person adelphus; 20.03.2012
comment
@adelphus: «Разработчик», который читает CLR, никогда не вызовет Main(null) и увидит, что мне не нужно проверять, передал ли мне кто-то 4 ... а. Может быть, ему следует проверить на ноль, с единственной целью дать понять остальному миру, что он не знает, что, черт возьми, он делает. Это два разных случая. Никто не говорит, что вы не должны проверять то, что вам передает код другого пользователя. Но вы можете доверять системе, чтобы она выполняла свою работу — или, скорее, если вы не можете, то вы также не можете доверять чему-либо, работающему в системе (даже вашему собственному коду!). - person cHao; 20.03.2012
comment
Я понял, что можно задать вопрос по теме и получить за него много баллов :) Действительно удивительно, как простой вопрос приводит к связанной долгой битве, в которой нет победителей... - person Tigran; 20.03.2012
comment
Удивительно грустно, наверное. Это действительно не должно было превратиться в то, что оно сделало. - person cHao; 21.03.2012
comment
@cHao: почему грустно?? Это id Q&A, а также дискуссионный форум. Хорошо иметь кого-то, кто может предложить разные решения. В решениях, может быть, я не уверен или даже не думал о них. - person Tigran; 21.03.2012
comment
@Tigran: Печально, потому что это был простой вопрос да/нет. Там не так много места для различных решений. Это и ответы, с которыми я спорил, настолько явно неправильны. :P Это слепая паранойя и карго-культизм. - person cHao; 21.03.2012

Если входных данных нет, то args.Length равен 0, но не равен нулю. Если есть какие-либо входные данные, то agrs.Length равно количеству входных аргументов. В заключение, args не может быть нулевым, но длина может быть нулевой.

PS всегда сначала проверяйте значение null

person Rinat    schedule 19.03.2012

person    schedule
comment
Вы можете упростить это, используя if (args == null) { ... } else if (args.Length == 0) { ... } else { ... } и сохранив слой фигурных скобок. FWIW, в большинстве случаев ветки для null и пустого массива, вероятно, все равно одинаковы. - person Joey; 19.03.2012
comment
@Joey о скобках Я думаю, что это более читабельно для других, а во втором комментарии вы ошибаетесь, это случай args нулевой, проверка args.Length вызовет исключение NullReferenceException! - person Dor Cohen; 19.03.2012
comment
Вот почему вы проверяете сначала null и затем Length: if (args == null || args.Length == 0) ... - person Joey; 19.03.2012