Question

In our project, we define two three build configurations, Release, Debug and 'Debug-plus-contracts'. These are defined as below:

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
  <Optimize>true</Optimize>
  <DebugType>pdbonly</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
  <DefineConstants>TRACE;DEBUG</DefineConstants>
  <DebugType>full</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug-plus-contracts'">
  <DefineConstants>TRACE;DEBUG;CONTRACTS_FULL</DefineConstants>
  <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
  <CodeContractsRuntimeThrowOnFailure>False</CodeContractsRuntimeThrowOnFailure>
  ...

We define two debug configurations because 'Debug-plus-contracts' only builds on machines with Code Contracts for .NET installed

My question is, what happens to a line such as Contract.Requires(source.Any()) when it's compiled in each configuration? Suppose it's violated at runtime, in which configurations will anything happen?


I ask because I heard (somewhere) that in the Debug configuration, Contract.Requires is compiled to Debug.Assert . But evidence suggests this isn't true, we have some Contract.Requires that fail in Debug-plus but not in Debug.

Was it helpful?

Solution

Contract.Requires is declared as

[ConditionalAttribute("CONTRACTS_FULL")]
public static void Requires(
  bool condition
)

[ConditionalAttribute("CONTRACTS_FULL")]
public static void Requires(
  bool condition,
  string userMessage
)

which means that if the CONTRACTS_FULL symbol is not defined, any call to Requires will be removed by the compiler completely. The check will not be performed at all.

If you do define the CONTRACTS_FULL symbol, but you don't have Code Contracts installed at build time or do not use its rewriter, any call to Requires will throw an exception regardless of whether the check passes, telling you that without the Code Contracts rewriter, it won't work.

Note: this is different from Contract.Requires<TException>. The latter does not have the same ConditionalAttribute, so will fail in any configuration unless the Code Contracts rewriter is used.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top