How to undefine the symbol CONTRACTS_FULL? - c#

Visual Studio defines the CONTRACTS_FULL symbol automatically if
you enable contract checking in the Code Contracts tab of the Project
Properties page.
- C# 5.0 In a Nutshell (page 518)
I'd like to disable/undefine the symbol but it doesn't appear in the Conditional compilation symbols field of the Build tab in the project settings.
(I'm not interested in disabling code-contracts completely! by that I simply mean that setting the contract checking to None is not a solution).
If it matters, the reason I want to do this is because in my release builds I only want to throw on Contract.Requires<TException>, and I don't want to throw ContractException at all.
One "solution" I found is to put #undef CONTRACTS_FULL at the first line of each file, it fixed it but actually doing that would be horrible.
(BTW up until now VS didn't define CONTRACTS_FULL and I had to define it myself, but I guess some setting changed accidentally)

You cannot run the contract tools and undefine the CONTRACTS_FULL symbol. The tools depend on that being defined. Nothing will work if you try to force this. That is why we define the symbol automatically inside the msbuild scripts.
Users of the Code Contract tools should never manually try to define or undefine the CONTRACTS_FULL symbol as it is a tool controlled variable.

I've read that book, and there WAS a contract level that only used Contract.Requires. It was the option before none in there, but it's somewhere in that section in the book, definitely.
However, I can't help you with globally undefing CONTRACTS_FULL. Sorry. I think though that in that contract checking level it's automatically undef'd.
EDIT: Yeah, you need to put it at level one (ReleaseRequired).

Related

Setting individual StyleCop rules as build errors

According to this blog, you can set all/certain projects to treat StyleCop violations as build errors instead of warnings:
By default, StyleCop violations will show up as build warnings. To turn StyleCop violations into build errors, the flag StyleCopTreatErrorsAsWarnings must be set to false. This flag can be set as an environment variable on the machine, or within the build environment command window. Setting the flag this way will cause StyleCop violations to appear as build errors automatically for all projects where StyleCop build integration is enabled.
Alternately, this flag can be set within the project file for a particular project. Open the .csproj file for your project again, and find the first PropertyGroup section within the file. Add a new tag to set the StyleCopTreatErrorsAsWarnings flag to false.
This doc shows where you can turn on/off individual rules, but it doesn't seem to support setting the severity, only completely turning them on/off.
Is it not possible to have more granular control of which rules result in errors vs. warnings?
It's not supposed to, but if you really want it.. why not?
Here is an idea, not a complete solution.
There are two useful lines in StyleCop.Targets file. First one imports StyleCop task:
<UsingTask AssemblyFile=".\StyleCop.dll" TaskName="StyleCopTask"/>
and this one calls it:
<StyleCopTask
ProjectFullPath="$(MSBuildProjectDirectory)"
SourceFiles="#(StyleCopFiles)"
AdditionalAddinPaths="#(StyleCopAdditionalAddinPaths)"
ForceFullAnalysis="$(StyleCopForceFullAnalysis)"
DefineConstants="$(DefineConstants)"
TreatErrorsAsWarnings="$(StyleCopTreatErrorsAsWarnings)"
CacheResults="$(StyleCopCacheResults)"
OverrideSettingsFile="$(StyleCopOverrideSettingsFile)"
OutputFile="$(StyleCopOutputFile)"
MaxViolationCount="$(StyleCopMaxViolationCount)"
/>
So you basically need to call it twice, first one specifying TreatErrorsAsWarnings as false (so that it fails if there are any warnings), and second one with true (resulting in just warning).
Also, you will need to use two separate settings file - first one with stylecop 'errors', second with 'warnings'.

how to install and use Code Contracts?

I have a basic question, might be it is so obvious but for some reason i can't seem to be successful with installing and using Code Contracts.
I've downloaded the package from MSDN, installed it following the online documentation but i still get an IDE warning for the below code statement:
Contract.Requires(inputParameter != "");
the IDE warning is:
"Method invocation is skipped. Compiler will not generate method invocation because the method is conditional, or it is partial method without implementation"
Anything I'm missing in the process of enabling Code Contracts? I'm using VS2010 Ultimate SP1
Most likely this is due to Code Contracts not being configured in the project settings. If you go to your project properties, you should see a Code Contracts tab. On the tab, select the mode you are building in (Debug|Release|Both) and then turn on Code Contracts features by checking the appropriate check boxes.
I've seen the warning that you detail when Code Contracts are not set to Build.
If you don't see the Code Contracts tab, then you might need to install Code Contracts on your machine. Do this by downloading and installing the installer from here.
Conditional compilation is all driven from compiler preprocessor definitions. This is the same approach used for the DEBUG constant, although Visual Studio hides the definition of that behind a checkbox. It's an efficient approach because when those symbols aren't defined then the methods aren't called at all; importantly the parameters being passed aren't evaluated either, so you can use relatively expensive checks in your code contracts without worrying about those checks slowing down release builds.
Microsoft's introduction to Code Contracts says this:
Most methods in the contract class are conditionally compiled; that is, the compiler emits calls to these methods only when you define a special symbol, CONTRACTS_FULL, by using the #define directive. CONTRACTS_FULL lets you write contracts in your code without using #ifdef directives; you can produce different builds, some with contracts, and some without.
Although this talks about using #define in the code to turn on code contracts:
#define CONTRACTS_FULL
as #NirMH said in the comments it's usually better to define it in the conditional compilation symbols for the project so you can have it on for some builds and off for others.
Note that CONTRACTS_FULL is the only option you have, although it's clearly been named to allow the possibility of more granular control in future.

Can I set a C# preprocessor directive from a central file?

I need to add some logging to my app, and it needs to be in release mode, and I need to make sure that the logging code isn't running in production. Therefore I'd like to use a #define and #if to make sure the log statements are removed when I move to production.
Trouble is, I need the logging in multiple files, and it's a pain to put a #define at the top of every file. Is there a way to have a centralized #define? That way I can remove the single #define rather than a #define from all files(which means I'll almost assuredly forget one).
On the command line, use the /define switch. In Visual Studio, choose the "Build" tab from the properties page for the project and fill in the "Conditional Compilation Symbols" section.
Consider also instead of using conditional compilation, to instead make your logging methods conditional methods. That's a more pleasant-looking alternative. That's how Debug.Assert works; it is a conditional method, so if the debug preprocessor symbol is not defined, the compiler simply removes all calls to the method before code generation.
See also my article on the subject:
http://ericlippert.com/2009/09/10/whats-the-difference-between-conditional-compilation-and-the-conditional-attribute/
Are you using Visual Studio? In the project Properties page, on the "Build" tab, there's a "Conditional compilation symbols" text box.
Yes, this is typically done in your build file, or the script you use which creates your build. You specify it as command-line arguments to MSBuild.
To add to Dave's answer, global conditional compilation symbols can also be specified in Visual.
Right-click on your project and go to Properties
Go to the Build tab
You can specify the symbols that you like (DEBUG is already turned on by default for Debug configurations, so this might actually give you what you want already) for the given configuration, or select "All Configurations" at the top to specify certain symbols for all configurations.
Call the logging everywhere you want.
Define the logging api entry methods with
[Conditional ("DEBUG")]
public void WriteDebugMessage(...)
Build your program in debug mode (which, by default, defines 'DEBUG' in VS). These calls will be part of your assembly.
Build your program in release mode (or - remove the DEBUG symbol from the build definition). These calls are now meaningless no-ops and won't run.
Seems like what you want?

How to set project wide #define in C#

I have several classes in a project which need to only be in certain builds of the application which are currently not ready for release or debug.
To prevent these classes from being used, I want to set around them this:
#if USE_MYCLASS
// Code here...
#endif
Unfortunately, I don't know how to setup a project-wide #define.
Is there functionality in Visual Studio to set project-wide definitions?
If there is, though I don't need it right now, is there a functionality to set solution-wide definitions?
If there is no functionality for such (seeing as C# does not have include files, I suppose it's possible), is there any method or plugin of doing this functionality without using the command line compiler and /D?
You can do that in the project properties, but not in source code.
Project Properties => Build => Conditional compilation symbols
You can specify whichever symbols you need (space delimited, but IIRC is is quite forgiving). Note that DEBUG and TRACE can also be toggled with a checkbox.
I have some projects with multiple "release" build configurations, with different symbols in each (for building 2.0 vs 3.0 vs 3.5 versions - see <DefineConstants> here)

.NET [SuppressMessage] attributes in shipping assemblies fxcop

I wonder if people (meaning the company/developers) really care about having [SuppressMessage] attributes lying around in the shipping assemblies.
Creating separate configs in the Project files that include CODE_ANALYSIS in Release mode and then yanking it off in the final build seems kind of an avoidable overhead to me.
What'll be the best stratergy, if one does not want these to remain in the final assembly but still want to use them in code ?
and Is there any advantages/disadvantages of storing them in FxCop Project files ?
[I'm coming from a VS2008 Pro+FxCop 1.36, rather than VS2008 Team System]
The SuppressMessage attribute will only be added to your code if the CODE_ANALYSIS preprocessor definition is present during a compile. You can verify this by looking at the definition of the attribute in Reflector.exe. By default this is not defined in Release so it won't affect production code.
Typically, I only run FxCop on DEBUG builds of my assembly where CODE_ANALYSIS is defined.
In the grand scheme of things, I don't think it really matters. Since this is an attribute (effectively meta-data), it doesn't impact code performance. That being said, do remember that the information in the attribute is available to anyone using a disassember like Reflector.
The problem with storing them in the FxCop project file is that you must then ensure that everyone uses the same project file and that the project file always travels with the project (it's checked in to source control, which means you must check it out each time you want to run FxCop).
If you don't want the SuppressMessage attributes in your production code you would need to only define the CODE_ANALYSIS symbol in the build you are running FxCop against. This does mean defining it either on your Debug configuration or adding additional configurations. The attributes will only be compiled in to the code when the symbol is defined.
From an automated/nightly build viewpoint, you can build using a configuration that has the symbol defined and then build the production release without the symbol or do two builds - one with the symbol defined, run FxCop to get your violations, and then another build without the symbol defined.
We have a ton scattered around production code, and we don't particularly care. It doesn't effect perf, and having some crufty looking attribute in a class often gives motivation to remove it if at all possible.

Categories