Top 10 ошибок .NET разработчиков по версии StackOverflow

понедельник, 8 ноября 2010, Александр Краковецкий

На StackOverflow был задан вопрос на тему: какие типичные ошибки .NET разработчиков вы можете назвать? Ниже представлен короткий отчет из этого обсуждения.

1. Сама частая ошибка, которую допускают .NET разработчики, состоит в том, что они обычно пишут

<code>throw ex;<br /></code>

вместо

<code>throw;<br /></code>

В первом случае stack trace будет обнулен, в то время когда второй вариант сохранит всю цепочку вызовов. Очень критично для отладки и логгирования приложений. Первый вариант нельзя использовать, если вы хотите повторно бросить исключение.

Более детально можно почитать об этом здесь.

2. Далее идет работа со строками:

<code>string s = "Take this out";<br />s.Replace("this", "that");  //wrong<br /></code>

Этот код не изменяет строку s, а правильный код выглядит таким образом:

<code>s = s.Replace("this", "that");  //correct<br /></code>

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

3. Никогда не используйте "магические числа":

Например:

<code>if(mode == 3) { ... }<br />else if(mode == 4) { ... }<br /></code>

В качестве альтернативы предлагается использовать перечисления (enums):

<code>if(mode == MyEnum.ShowAllUsers) { ... }<br />else if(mode == MyEnum.ShowOnlyActiveUsers) { ... }<br /></code>

4. Дальше расположился ответ с рядом советов:

5. Очень правильное замечание - использовать больший уровень абстракции ваших классов и методов.

Например, у вас есть функция:

<code>public void Foo(List<Bar> bars) <br />{<br />  foreach(var b in bars)<br />  {<br />    // do something with the bar...<br />  }<br />}<br /></code>

Более правильный вариант - это использовать IEnumerable:

<code>public void Foo(IEnumerable<Bar> bars) ...<br /></code>

Теперь функция может принимать не только List, но и массивы, коллекции и т.д.

Замечание: ReSharper выдаст вам предупреждение.

6. Необходимо использовать using блоки для того, чтобы быть уверенным, что Dispose() будет вызван.

7. Еще один отличный совет, который можно отнести не только к .NET, но и к разработке в целом: "не нужно начинать писать что-то перед тем, как не подумал".

Еще один совет - избегать пустых catch - конструкций в своем коде:

<code> try<br />{<br />    //something<br />}<br />catch<br />{<br />    // do nothing<br />}<br /></code>

Ах, какая знакомая конструкция...

8. Преобразование типов с помощью as:

<code>Tree tree = obj as Tree;<br /></code>

... необходимо использовать только если вы ожидаете, что obj может быть не только типа Tree.

Если вы уверены, что obj всегда имеет тип Tree, то лучше использовать такой вариант:

<code>Tree tree = (Tree)obj;<br /></code>

Вариант

<code>Tree tree = obj as Tree;<br />if( tree != null )<br />{<br />    tree.GrowBranch();<br />}<br /></code>

автор отбрасывает по причине абсурдности и считает, что программа должна остановиться (выдать исключение), если пришло что-то отличное от того, что мы ожидали:

<code>if( thisComputersPowerHasFailed )<br />{<br />    SendEmailToAdministratorToSaySomethingHasGoneWrong();<br />}<br /></code>

Честно говоря, не согласен с автором этого комментария, так как тоже придерживаюсь мнения, что использование as + проверка на null является bug-free, работает быстро и является хорошим примером самодокументированного кода. Хотя логику автора также можно понять.

9. "Ensure that the debug="false" on the element in the web.config file of each and every ASP.NET application on the server. The default during development is "true" and it is a common mistake to allow this development time setting to find its way onto production servers during deployment. You don't need it set to true in production and it often leads to memory overhead and inefficiencies."

При развертывании веб-приложения в оставлять Debug="true" в web.config. Сомнительно, но автор приводит доказательства в виде этой статьи, где говориться, что timeout будет меньше, а JIT компилятор не сможет оптимизировать код.

Для проверки проектов можно воспользоваться встроенной командой finddebugtrue из WinDBG, которую нужно выполнить для дампа памяти ASP.NET приложения:

!finddebugtrue

результат:

0:016> !finddebugtrue

Debug set to true for Runtime: 61b48dc, AppDomain: /MyDebugApplication

Debug set to true for Runtime: 1f50e6d8, AppDomain: /MemoryIssues

Total 16 HttpRuntime objects

В общем, надо копнуть в этом направлении поглубже...

10. Ну и завершает топ 10 классическая ошибка - использование string вместо StringBuilder при большом количестве операций над строками.

Плохой код:

<code>for(int i=0; i<100000;i++) <br />{</code><br /><code>    string s = "This ";<br /></code><code>    </code><code>s += "is ";<br /></code><code>    </code><code>s += "not ";<br /></code><code>    </code><code>s += "the ";<br /></code><code>    </code><code>s += "best ";<br /></code><code>    </code><code>s += "way.";<br />}<br /></code>

Хороший:

<code>StringBuilder sb = new StringBuilder();<br /></code><code>for(int i=0; i<100000;i++) <br />{<br />    sb.Append("This ");<br />    sb.Append("is ");<br />    sb.Append("much ");<br />    sb.Append("better. ");<br />}<br /></code>

От себя добавлю, что в данном случае мне больше нравится вариант:

<code>string s = @"This <br />is<br />not<br />the<br />best<br />way.";</code>

но суть, надеюсь, понятна.

А какие типичные ошибки вы можете назвать?


Ищите нас в интернетах!

Комментарии

Свежие вакансии