我刚刚安装了新发布的Visual Studio 2017 Enterprise(RC)。然而,我在将其与Code Contracts一起使用时遇到了问题。但是,在Visual Studio 2015中使用Code Contracts没有任何问题。我有什么遗漏吗?
我刚刚安装了新发布的Visual Studio 2017 Enterprise(RC)。然而,我在将其与Code Contracts一起使用时遇到了问题。但是,在Visual Studio 2015中使用Code Contracts没有任何问题。我有什么遗漏吗?
CCRewrite
进行运行时验证的支持。
注意:此版本不支持通过项目属性窗格进行配置。因此,代码合同需要通过手动向
csproj
文件添加适当的属性来配置。有关属性列表的详细信息,请参见@crimbo的答案。
不幸的是,尽管这些更新已合并到主代码分支中,但它们既没有反映在Marketplace distribution中,也没有反映在官方NuGet Package中。因此,您需要从存储库下载和编译源代码(这很容易;只需使用提供的BuildCC.bat
文件)。
CodeContracts.MSBuild
添加到您的packages.config
中:Install-Package CodeContracts.MSBuild -Version 1.12.0
背景:Igor Bek最初将此软件包组合在一起,作为代码契约团队的概念验证, 后来它成为了官方NuGet软件包的基础(在v1.10.10126.2中)。由于Microsoft没有更新官方NuGet软件包,因此他的软件包现在是最新的。
鉴于目前的支持状态,我不鼓励人们为新项目采用代码契约,但这应该为已经投资于现有.NET Framework项目的开发人员提供向后兼容性。
目前为止,在VS2017中还没有合同定义,但是如果使用Nuget包DotNet.Contracts,则可以通过以下方法解决:
DotNet.Contracts.1.10.20606.1\MsBuild
)v14.0
文件夹v15.0
一切都应该如预期地构建。
@JeremyCaney
的答案,我安装了 NuGet 包 CodeContracts.MSBuild。这个和编辑 .csproj 文件以指定配置是你需要做的全部。 - IgorAdd the contents of C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.Targets\ImportAfter\CodeContractsAfter.targets
to your csproj files (either directly or indirectly via an import). The most basic approach is to add this to your csproj file:
<PropertyGroup>
<CodeContractsInstallDir Condition="'$(CodeContractsInstallDir)'==''">C:\Program Files (x86)\Microsoft\Contracts\</CodeContractsInstallDir>
</PropertyGroup>
<Import Condition="'$(CodeContractsImported)' != 'true' AND '$(DontImportCodeContracts)' != 'true'" Project="$(CodeContractsInstallDir)MsBuild\v$(VisualStudioVersion)\Microsoft.CodeContracts.targets" />
CodeContractsInstallDir
应该被指定为环境变量。在这种情况下,您只需要添加以下代码即可:
<Import Condition="'$(CodeContractsImported)' != 'true' AND '$(DontImportCodeContracts)' != 'true'" Project="$(CodeContractsInstallDir)MsBuild\v$(VisualStudioVersion)\Microsoft.CodeContracts.targets" />
添加到您的 *.csproj 文件中。
Specify all the CodeContracts properties in your *.csproj file (directly or indirectly via Import). Eg:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Code Contracts settings -->
<PropertyGroup>
<CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
<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>
<CodeContractsInferRequires>False</CodeContractsInferRequires>
<CodeContractsInferEnsures>False</CodeContractsInferEnsures>
<CodeContractsInferObjectInvariants>False</CodeContractsInferObjectInvariants>
<CodeContractsSuggestAssumptions>False</CodeContractsSuggestAssumptions>
<CodeContractsSuggestRequires>True</CodeContractsSuggestRequires>
<CodeContractsSuggestEnsures>False</CodeContractsSuggestEnsures>
<CodeContractsSuggestObjectInvariants>False</CodeContractsSuggestObjectInvariants>
<CodeContractsDisjunctiveRequires>False</CodeContractsDisjunctiveRequires>
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
<CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
<CodeContractsCacheAnalysisResults>True</CodeContractsCacheAnalysisResults>
<CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
<CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<CodeContractsRuntimeCheckingLevel>ReleaseRequires</CodeContractsRuntimeCheckingLevel>
</PropertyGroup>
</Project>
csproj
文件的需要。 - Jeremy Caneycsproj
文件中设置了它们。但是,它们绝对是必要的,否则无法同时启用静态检查和运行时验证。 - Jeremy CaneyC:\Program Files (x86)\MSBuild\4.0\Microsoft.Common.Targets\ImportAfter\CodeContractsAfter.targets
C:\Program Files (x86)\Microsoft Visual Studio\2017\#YourVS2017Product#\MSBuild\15.0\Microsoft.Common.targets\ImportAfter
Contract.Requires()
非常简化版,只需要在调用类中全局替换using
声明即可。using MYCommon.Diagnostics; //System.Diagnostics.Contracts;
如果/当System.Diagnostics.Contracts
在VS 2017和.NetStandard中可用,那么恢复到正确版本将变得更加容易。
实际的类是:
/// <summary>
/// Contract.Requires(config != null); in VS 2017 not throw ArgumentNullException
/// The class is workaround for https://dev59.com/tFkR5IYBdhLWcg3w1wch
/// </summary>
public class Contract
{
public static void Requires(bool condition, string message = null)
{
Requires<ArgumentNullException>(condition, message);
}
public static void Requires<TException>(bool condition, string message=null) where TException:Exception , new ()
{
if (!condition)
{
//https://dev59.com/kXVD5IYBdhLWcg3wQJKT#41450
var e=default(TException);
try
{
message = message ?? "Unexpected Condition"; //TODO consider to pass condition as lambda expression
e = Activator.CreateInstance(typeof(TException), message) as TException;
}
catch (MissingMethodException ex)
{
e = new TException();
}
throw e;
}
}
}
基本限制在于典型用法Contract.Requires(param1!=null);
不能让我抛出参数名称的异常,更好的用法稍微长一些:
Contract.Requires<ArgumentNullException>(param1!=null, "param1 is null");
Requires()
的运行时验证,那么这是一种有效的策略。它可以扩展到支持Assert()
、Assume()
、Exists()
和ForAll()
,而不需要太多的努力。然而,如果需要支持Ensures()
、Invariant()
、Result()
或ValueAtReturn()
,使用这种方法将是不切实际的(除非对调用者进行重大重构)。换句话说,这只适用于验证前置条件的简写。 - Jeremy CaneyEnsure
的支持使得这个问题存在争议。另一方面,使用Require
很容易,但使用Ensure
则非常困难。 - Wiktor Zychla