вторник, 22 октября 2013 г.

Вредные советы от ReSharper


Установил ReSharper и был откровенно удивлен некоторыми рекомендациями его Code Inspection...

Использование readonly не по назначению


Если только объявлено поле (field), значение которому не присваивается нигде, кроме конструктора или прямой инициализацией, ReSharper будет настойчиво уговаривать сделать его readonly. Это вполне понятно и объяснимо, когда это поле представляет из себя простой (или немодифицируемый) тип данных вроде строки или целого числа. Но когда ReSharper предлагает делать readonly коллекции, которые модифицируются во время жизни класса, это напрягает. Это напоминает константные shared pointer в C++. Вроде бы нужно делать все, что явно не меняется константным, но только когда это соответствует ответственности класса, а не только какой-то формальной семантике.

Использование var вместо явного указания типа


Здесь [...] авторы защищают это предложение. Даже microsoft не советуют применять var для неанонимных типов, но у JetBrains "свое мнение".
Якобы делает код "чище". По моему это просто еще один вид отказа от выбора имени для сущности. Самого кода, естественно, будет меньше. Но пострадает читабельность. При явном указании типа сразу понятно, с чем дальше мы будем иметь дело. А при использовании var остается либо догадываться, либо лезть в объявление метода, который вернул нам этот класс. Якобы это приводит к лучшему API. С чего вдруг? Скорее наоборот, разработчики будут вставлять имена возвращаемых типов в имена методов. Якобы убирает шум из кода. Ну какой шум? Наоборот, убирает сигнал, то есть важную информацию. Единственное, с чем можно согласиться, так это с тем, что использование var требует явно инициализировать переменные при объявлении.

четверг, 10 октября 2013 г.

Бесконечная рекурсия сводит Microsoft unit testing framework с ума

Совершенно случайно наткнулся на странное поведение юнит-тестов Microsoft. Нажимаю запуск всех тестов, проходит несколько секунд... И возвращаюсь в исходное состояние. Тестов как будто и не запускалось...Никаких ошибок, исключений, предупреждений, ничего... Некоторые тесты по отдельности запускались и успешно отрабатывали, а некоторые нет...
При отладке одного из тестов, вводящих Visual Studio в ступор, я увидел-таки заветную ошибку "An unhandled exception of type 'System.StackOverflowException' occurred". Получается, что при ошибке переполнения стека (например, из-за бесконечной рекурсии) простой запуск юнит-тестов не возвращает ошибку, а исключение "проглатывается" системой запуска тестов...
Например, такой код приведет к подобному поведению:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace RecursionUnitTest
{
    public class Recurse
    {
        public int Run()
        {
            return Run();
        }
    }

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestRecursion()
        {
            Recurse rec = new Recurse();

            Assert.AreEqual(0, rec.Run());
        }
    }
}