как мне объяснить, что если (xyz == null) проверки не являются «защитными»

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

  •  22-07-2019
  •  | 
  •  

Вопрос

У меня есть несколько разработчиков, которые постоянно ставят, если проверяет NULL

Например:

Run(Order order)
{
  if (order == null) return;
}

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

другое предложение - иметь предварительное условие или класс охраны, которые быстро терпят неудачу и генерируют исключения. любая вещь, кроме игнорирования того факта, что у потребителя, вероятно, есть какая-то другая проблема, и я помогаю маскировать ее.

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

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

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

Решение

Если ваш класс не может принимать аргументы null , тогда лучше всего это сделать:

if (arg == null)
    throw new ArgumentNullException();

Это гораздо предпочтительнее для получения NullPointerException вглубь стека. В худшем случае вы куда-нибудь кешируете этот null и на самом деле не будете вызывать исключение намного позже, а посмотрим, насколько весело вы будете отлаживать проблему then .

И, как утверждают другие, иногда в контракте говорится, что null - это нормально. В этом случае правильное использование выражения guard для некоторых частей кода - хотя даже тогда я бы сказал, что лучшим вариантом было бы добавить перегрузку без необязательных аргументов null.

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

Это действительно зависит от конкретной ситуации. Редко рекомендуется давать общие рекомендации, такие как «не ставить нулевые проверки в вашем коде», как вы, похоже, указываете. Контракт класса должен определять, что законно, а что нет. Но если в контракте четко указано, что передача значения null недопустима, исключение действительно является подходящим ответом.

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

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

Я хотел бы добавить, что ArgumentNullException принимает параметр по причине.

Лучше написать

if(myArg == null) throw new ArgumentNullException("myArg");

чем бросить ArgumentNullException без paramName .

Таким образом, если у вас есть исключение из функции, которая принимает пять параметров, вы будете знать, какой из параметров вызвал проблему. Это особенно важно, если вы не можете подключить отладчик. (Например, на рабочем веб-сервере или компьютере конечного пользователя)

Если вы пишете много функций, это может привести к большим накладным расходам, тем более что IntelliSense для строк не существует. Я написал фрагмент кода для генерации этих проверок:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Check for null arguments</Title>
            <Shortcut>tna</Shortcut>
            <Description>Code snippet for throw new ArgumentNullException</Description>
            <Author>SLaks</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
                <SnippetType>SurroundsWith</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>Parameter</ID>
                    <ToolTip>Paremeter to check for null</ToolTip>
                    <Default>value</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[if ($Parameter$ == null) throw new ArgumentNullException("$Parameter<*>quot;);
        $end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

Контракты кода в .net 4.0, надеюсь, сделают это поведение более согласованным. Любые статьи, в которых говорится о контрактах кода, помогут донести идею, и в будущем этот вид синтаксиса предоставит метод.

http : //blogs.msdn.com/bclteam/archive/2008/11/11/introduction-to-code-contracts-melitta-andersen.aspx

Я не просматривал его, но eiffel.com имеет 2 презентации ( слайды + аудио) на тему дизайн по контракту . У этих ребят есть концепция , так что если кто-то может это объяснить, то это они :-)

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

Если в контракте метода указано, что его аргументы не должны быть нулевыми, то правильно сделать его явным, используя Assert, например так:

Debug.Assert( item != null, "Null items are not supported );

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

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

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

Все ошибки являются или кажутся глупыми, как только они обнаружены. Но его проверки, как это, дразнят их, чтобы выставить себя. До тех пор ошибки невидимы. А для больших и достаточно сложных проектов вы не знаете, кто найдет ошибку или при каких условиях она будет обнаружена. Код, который спроектирован для обеспечения устойчивости, обычно имеет такие проверки повсеместно, а также проверяет возвращаемые значения для каждой функции, которая должна включать значения ошибок. Таким образом, вы в конечном итоге кодируете «я не могу этого сделать, потому что не работают подфункции, на которые я полагаюсь»; семантика, которая на самом деле обрабатывается правильно. Большая ценность этого в том, что вы обычно можете легко реализовать обходные пути или самосознательные средства отладки. Почему вы хотите делать такие вещи, потому что наиболее сложные ошибки обычно зависят от обоих этих свойств для правильной отладки.

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

Короче говоря: ни один код не сделан устойчивым, если исходить из устойчивости среды вокруг них.

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