Top 10 ошибок .NET разработчиков по версии StackOverflow
На 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. Дальше расположился ответ с рядом советов:
- если вы используете структуры (struct), то нужно помнить, что они их лучше их делать immutable
- при переопределении Equals не забывать переопределять GetHashCode (а также != и ==)
- нужно бережно относиться к статическим переменным в web-приложениях
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
При развертывании веб-приложения в оставлять 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>
но суть, надеюсь, понятна.
А какие типичные ошибки вы можете назвать?