На сайте DevLabs (разработчиков Code Contracts) написано, что Visual Studio Express не поддерживается. Мне это показалось весьма странным, с учетом того, что System.Diagnostics.Contracts включен в .Net Framework 4. Конечно, Express версии не поддерживают PlugIn’ов, но ведь это совсем не повод, чтобы отказываться от использования CodeContract’ов, тем более, что все равно нужно выкачивать и устанавливать на машину разработчика то, что и называется CodeContracts. Установка содержит
- ccrewrite утилита для осуществления проверки во время выполнения;
- ccdoc утилита для генерации документации;
- набор бибилиотек для .Net Framework’a 3.5 (по-моему, 3’й не поддерживается)
Премиум также содержит cccheck статический анализатор времени компиляции;
После установки в Visual Studio, в версиях выше Professional, в свойствах проекта появляется еще одна закладка: “Code Contracts”
Если отжать Perform Runtime Checking, то контракты начинаю срабатывать.
Если после этого открыть проект в Express версии (или в #Develope ), то контракты продолжат работать, не смотря на то, что закладки “Code Contacts” в свойствах проекта не появляется.
Итак, что же изменилось? А изменяется вот что: в файле проекта добавляются строки описывающие поведение контрактов.
Чтобы увидеть изменения нужно открыть сам файл проекта (.csproj для С#) в текстовом виде:
- В VS Professional и выше: выгружаем проект в Solution Explorer, правой кнопкой щелкаем на проект и выбираем Edit ProjectName.csproj;
- в Express версии, просто лезем в папку с проектом и открываем любым простейшим текстовым редактором.
В каждую PrepertyGroup соответствующую вариантам сборки (X86/Debug/Release) добавились следующие строчки:
<CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
<CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
<CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
<CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
<CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
<CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
<CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
<CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
<CodeContractsEnumObligations>False</CodeContractsEnumObligations>
<CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
<CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
<CodeContractsCustomRewriterAssembly />
<CodeContractsCustomRewriterClass />
<CodeContractsLibPaths />
<CodeContractsExtraRewriteOptions />
<CodeContractsExtraAnalysisOptions />
<CodeContractsBaseLineFile />
<CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
<CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
<CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
Привожу, за что какие параметры отвечают:
- CodeContractsEnableRuntimeChecking: если значение установлено в true, ccrewrite будет вживлять в проект проверку условий контракта. Фактически проверки выполнения контрактов начинаются с установки этого значения и для того чтобы разобраться с использованием достаточно включить только его;
- CodeContractsRuntimeCheckingLevel: устанавливает уровни использования контрактов, то есть можно включить проверку только пред или постусловий. Принимаемые значения: Full, Pre and Post, Preconditions, ReleaseRequires или None;
- CodeContractsRuntimeThrowOnFailure: если установлено в true, то контракт будет выбрасывать исключение. Если false, то проверка контракта будет вести себя как Debug.Assert;
- CodeContractsRuntimeOnlyPublicSurface: если установлено true, то обрабатываются только публичные методы;
- CodeContractsRuntimeCallSiteRequires: когда установлено true, реврайтер внедряет контракты в вызывающие ваш код приложения; ;
- CodeContractsReferenceAssembly: принимает значения {Build, DoNotBuild, None}. Если выставить в Build, то создается дополнительная сборка с набором контрактов для этого проекта. Это нужно если на ваш проект ссылается еще один и ему нужно видеть, какие контракты используются или если вы хотите генерировать документацию по контрактам;
- CodeContractsEmitXMLDocs: если установлено в true вместе с CodeContractsReferenceAssembly, генерируемая документацию к сборке будет содержать описание контрактов;
- CodeContractsCustomRewriterAssembly: указывает пусть к сборке содержащей свою реализацию методов реврайтера;
- CodeContractsCustomRewriterClass: содержит имя класса в котором реализованы методы, используется вместе с CodeContractsCustomRewriterAssembly;
- CodeContractsLibPaths: здесь указываются через точку с запятой пути к дополнительным сборкам содержащим контракты;
- CodeContractsRunCodeAnalysis: значение включает статическую проверку кода собираемого проекта;
- CodeContractsNonNullObligations: когда установлено true, статический анализатор будет пытаться проверять все ссылки на корректность;
- CodeContractsBoundsObligations: когда установлено true, статический анализатор будет пытаться проверять корректность указания границ массивов;
- CodeContractsArithmeticObligations: когда установлено true, статический анализатор будет пытаться проверять корректность математических операций, таких как деление на ноль;
- CodeContractsRedundantAssumptions: когда установлено true, статический анализатор будет выдавать warning’и при “очевидных сравнениях” (не знаю как правильно перевести Redundant Assumptions) ;
- CodeContractsRunInBackground: если установлено в true, статический анализатор работает в фоновом процессе, не блокируя сборку проекта;
- CodeContractsExtraAnalysisOptions: используется для передачи дополнительных параметров статического анализатора;
- CodeContractsRuntimeSkipQuantifiers: если установлено в true, то некоторые контракты содержащие вызовы Contract.ForAll и Contract.Exists пропускаются. Это дает большую разницу в производительности;
- CodeContractsEnumObligations: если установлено в true, статический анализатор проверяет границы перечислений;
- CodeContractsShowSquigglies: включает подчеркивание волнистой линией ошибок;
- CodeContractsUseBaseLine: включает так называемую БазовуюЛинию. Она используется для того, чтобы статический анализатор мог отслеживать предупреждения только в изменяемом коде. При включении генерируется файл содержащий предупреждения и при последующих компиляциях они не отображаются;
- CodeContractsBaseLineFile: имя файла в который записываются предупреждения;
- CodeContractsExtraRewriteOptions: содержит дополнительные параметры для ccrewrite;
- CodeContractsCacheAnalysisResults: включает кэширование статическим анализатором результатов;
- CodeContractsAnalysisWarningLevel: устанавливает уровень эвристики статического анализатора.
Большинство этих параметров вносить не обязательно. Параметры, которые относятся к статическому анализатору можно точно откинуть, а остальные, за исключением CodeContractsEnableRuntimeChecking имеют вполне рабочие значения по умолчанию. Если вы хотите избавить свой проект от нагромождений if…throw,то достаточно использовать CodeContractsEnableRuntimeChecking.
Например.
Создаем в Visual Studio Express новый проект консольного приложения с таким кодом:
static void Main(string[] args)
{
PrintMessage("Привет");
Console.ReadLine();
}
static void PrintMessage(string str)
{
Contract.Requires(str.Length > 10,"Message to short");
Console.WriteLine("Сообщение: {0}",str);
}
Если приложение запустить, оно отлично отрабатывает, не смотря на то, что мы указали в контракте, что длина сообщения должна быть больше 10 символов.
Сохраняем, закрываем VS Express, вносим изменения в файл проекта, снова открываем проект в VS Express.
Контракты начинают срабатывать.
Комментариев нет:
Отправить комментарий