Подтвердить что ты не робот

Могу ли я оставить контракты в коде, которые я объединяю с кодовой базой, используемой разработчиками, не являющимися кодовыми контрактами?

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

Я разрабатывал побочный проект, используя Microsoft Code Contracts для проверки статического типа (отчасти потому, что я раньше их не использовал и хотел учиться).

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

Я использую .Net 4.5, поэтому включены библиотеки Code Contract, но мне интересно, будет ли Visual Studio жаловаться на то, что они не строят с CONTRACTS_FULL, указанными в настройках сборки, каждый раз, когда они идут на сборку, или, если я оставлю CONTRACTS_FULL в настройках сборки, что произойдет, когда другой разработчик попытается построить? Кроме того, мне интересно, как конечный продукт будет действовать, когда Контракт провалится, но код не был создан с помощью Rewriter Code Contracts.

Я создал новое решение только с одним проектом. Создал простую функцию, которая уволила нарушение кода, с отключенными кодовыми контрактами и CONTRACTS_FULL не указана. Построил и запустил его и получил следующую ошибку:

Run-time exception (line 8): An assembly (probably "hdxticim") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.Requires<TException> and the CONTRACTS_FULL symbol is defined.  Remove any explicit definitions of the CONTRACTS_FULL symbol from your project and rebuild.  CCRewrite can be downloaded from http://go.microsoft.com/fwlink/?LinkID=169180. 
After the rewriter is installed, it can be enabled in Visual Studio from the project Properties page on the Code Contracts pane.  Ensure that "Perform Runtime Contract Checking" is enabled, which will define CONTRACTS_FULL

Я думаю, что сообщение об ошибке нуждается в переписывании, поскольку CONTRACTS_FULL определенно не определен.

Благодаря Matías Fidemraizer мы выяснили, что это происходит при использовании Contract.Requires<TException>(), а не на Contract.Requires().

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

Здесь сценарий, демонстрирующий проблему: https://dotnetfiddle.net/cxrAPe

4b9b3361

Ответ 1

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

В противоречии с тем, что написал в своем ответе @CBauer, есть "благословенный" пакет для кодовых контрактов. Нет, это не пакет NuGet, это установка на базе установщика MSI.

Наконец, если вы работаете в среде непрерывной интеграции для отладочных сборников (например, разработки, QA/QC и/или тестирования), тогда эти серверы сборки также должны иметь установленные контракты кода.

Когда вы используете Code Contracts, сборки Debug всегда требуют использования кодовых контрактов. Обратите внимание, что это не обязательно случай для сборки релиза. Это зависит от того, какую форму проверки контракта вы используете, и параметров, указанных в свойствах проекта.

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

Следует отметить, что если вы используете форму предварительных условий Contract.Requires<TException>(bool condition), для создания релизов вы должны включить Code Contracts (см. Раздел 5: Рекомендации по использованию, в частности, стр. 20, сценарий использования 2).

Поскольку вы интегрируете этот код в существующую кодовую базу, которая не была разработана с помощью кодовых контрактов, вам следует рассмотреть возможность пересмотра параметров проекта Project Contracts Project, чтобы соответствовать сценарию использования 3, указанному на странице 20. руководство по кодовым контрактам, и переформулируйте свои контракты, используя шаблон "наследие" if-then-throw. Это позволит вашей команде наилучшим образом транслировать базу кода для использования кодовых контрактов повсюду, что позволит вам в конечном итоге заменить "предыдущие" проверки с предварительным условием "если-то-бросок" с фактическими кодовыми контрактами Contract.Requires(bool condition), а если хотите, Contract.Requires<TException>(bool condition) проверит.

ОБНОВЛЕНИЕ: скоро будет пакет NuGet для кодовых контрактов Сегодня я был в новом хранилище GitHub для кодовых контрактов. Для тех из вас, кто не знает, Microsoft открыла это с открытым исходным кодом, и теперь это усилия, направленные на сообщество.

Недавно они (в январе) объявили о выпуске v1.10.xxxx.RC1. Вы можете найти информацию об этом здесь, в своем репозитории GitHub.

Ответ 2

К сожалению, сложно сохранить библиотеку, которая не установлена ​​через nuget, не заставляя своих сотрудников поддерживать свою личную среду. Кодовые контракты, похоже, не имеют официального пакета Microsoft-blessed для использования.

Четвертьpastmidnight сообщение ниже имеет недавно обновленный ответ на мою первоначальную озабоченность выше, но нижняя половина, я думаю, остается актуальной даже сейчас. Получите ваш бай-ин, люди!

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

Ответ 3

Contract.Requires<TException>() не удастся, если не будет установлен перезаписывающий код, независимо от установки CONTRACTS_FULL или нет.

Одним из решений является создание отдельного класса FailableContract, который проверяет условие препроцессора CONTRACTS_FULL, которое задается Контрактами кода.

Тогда вам нужно только удалить CONTRACTS_FULL из ваших параметров сборки, прежде чем передавать код в базу кода. Вы все еще получаете кодовые контракты, все остальные получают защитные инструкции.

Небольшая часть FailableContract (которую я еще пишу):

public class FailableContract
{

    public static void Requires(bool condition)
    {
        #if CONTRACTS_FULL
            Contract.Requires(condition);
        #else
            if (!condition) throw new ArgumentException(); //Just go with an argument exception because we haven't been supplied with an exception type.
        #endif
    }

    public static void Requires<TException>(bool condition) where TException : Exception, new()
    {
        #if CONTRACTS_FULL
            Contract.Requires<TException>(condition);
        #else
            if (!condition) throw new TException();
        #endif
    }
}

Тогда простое Find, Replace Contract. to FailableContract. должно получить большинство проблем.