I'm wondering whether should I throw exceptions or call Contract.Requires<TException>
For example:
public static void Function(String str)
{
if (str == null) throw new ArgumentNullException("str", "Input string cannot be null.");
// ...
}
vs
public static void Function(String str)
{
Contract.Requires<ArgumentNullException>(str != null, "Input string cannot be null.");
// ...
}
Since Contract.Requires<TException> doesn't require the CONTRACTS_FULL symbol I can keep it in my release builds as well.
This is my consideration:
Con: You can't call an overloaded version of the custom exception type constructor. There is simply no way to pass additional parameters to the constructor.
Pro: Static tools support (e.g. inform the caller of contract violation).
Which one should I use, and for what kind of situation?
The basic trade-off between if-then-throw and Requires<TException> as documented in the CodeContract user guide is how you build with your release bits.
Case 1: You only use if-then-throw, no Requires<TException>. In this case you can build your release bits without running the contract tools on your dll/exe. The advantage is that you have faster builds and no risk that the tool introduces bugs. A second advantage is that team members can opt out of using the CodeContract tools. Disadvantages are that you get no contract inheritance of requires, and your contracts are not necessarily visible to the tools (unless you use EndContract). You specify this case by using assembly mode: Custom Parameter Validation
Case2: You decide to run the CodeContract tools on your release bits always. This lets you use Requires<TException> and you get inheritance of contracts, including instrumentation of interfaces etc. Your contracts are clean and tool recognizable. The disadvantage is that everyone building your code must have the CodeContracts tools installed. You specify this case by using assembly mode: Standard in the Contract property pane.
Hope this clear things up.
I'm not sure that there are any earth-shattering differences between the two approaches, but here are two reasons why I prefer contracts...
1) The code is much neater, as you are writing a statement at the top of the method that shows the assumptions upon which the method is based. You don't clog up the code with the implementation of what happens if the assumption is violated.
2) You get the benefit of Visual Studio picking up on the code contracts when you are writing code, and giving you hints as to what the method you are about to call expects. This helps you ensure that you are sending the method valid parameters, without having to jump to the method definition to check the code there.
Once the code is compiled and running, I don't think there are any significant differences.
Hope this helps.
Related
Being inspired by this article I asked myself how can I emit compiler errors or , at least stop the build, if a feature is not implemented.
The only quick solution I came up with, is by creating a custom attribute:
public class NoReleaseAttribute : System.Attribute
{
public NoReleaseAttribute()
{
#if RELEASE
.
#endif
}
}
The idea is to have a syntactic error somewhere, but only for Release. I used an attribute because the IDE will help me find quickly the references to the attribute, and thus all places that I marked as needed to be completed or fixed before going in production.
I don't like this solution because I want one to emit a compiler error in each place that needs attention, not a single global error elsewhere.
Perhaps there is a more fitted solution.
You may use #error directive in your code, it will cause an error at compile-time.
Example usage:
static void Main(string[] args)
{
DoSomeStuff();
}
#error Needs to be implemented
static void DoSomeStuff(){
//This needs some work
}
There are no more fitted solution. You can use for your goal:
a) ObsoleteAttribute (may not fit your goal)
b) throw NotImplementedException in every place that you need to:
#if RELEASE
throw new NotImplementedException();
#endif
c) Wrap throwing NotImplementedException with attribute as you described us.
Basically it is unnecessary to add code that will not be used anywhere - Visual Studio even marking this code with 0 usages and it will not be included in CIL. So you have to question yourself - do i really need useless code exist in our project? It is better to track unreleased features in tracking systems like YouTrack or something, than to search them in your code.
I would suggest using a build step that checks the code for TODO-comments and generates warnings for them. A quick google suggest the Warn About TODOs extension might do just that, but it is not something I have used. You should also configure your build to fail on most warnings. A possible risk here is that people will just avoid using todo-comments, since they will fail the build.
But needing such a check suggest you do not have sufficient testing of your code. I find it a good practice to at least do some level of testing before committing any code, and just about any testing should reveal if entire components are not implemented. Reviewing your own code before committing is another practice that could be useful.
Automated unit testing can be a great way to deal with things like this. If you write unit tests for all your components the tests should find things like this, especially if you throw NotImplementedException in placeholders. This might require you to write your tests before the components, but there are certainly arguments for such a development approach.
The next line of defense should be code review. Even a quick review should find methods that are not implemented.
The final line of defense should be independent testing. If someone else tests the new features against the specification, any significant missing functionality should be found.
Here is my problem. I am a very big fan of Design by contract, I am using this concept especially when developing libraries that can be used by other developers. I just found out a new way of doing this which is: Contract.Requires instead of Exception:
So instead of having:
public void SomeMethod(string name){
if(name==null) throw new NullArgumentException("Null values not supported");
}
I now have:
public void SomeMethod(string name){
Contract.Requires(name != null);
}
EDIT: I am working under VS2010 on debug mode.
Problem: Contract.Requires does not do anything, even when name is null!
The MSDN documentation says:
Specifies a precondition contract for the enclosing method or
property.
But nothing is specified in case the condition is not met!
I also noticed there are other Contract.Requires overloads that throw exception, display message... but then what is Contract.Requires(Boolean) for?
EDIT Answer below highlighted that a plug-in must be installed to have the full power of Contract API but then what about Mono users who want their code to behave the same on different platforms?
You should do the following:
Install the Code Contracts add-in as nfechner has noted
Go to the project properties, 'Code Contracts' folder
Check 'Perform Runtime Contract Checking'
Switch 'Assembly Mode' to 'Standard Contract Requires'
Substitute your Contract.Requires with Contract.Requires<SomeException> (the first one throws System.Diagnostics.ContractException while the second throws the exception you specified which is important for public methods)
That's the basic setup. For more accurate configuration, refer to the manual
If you use Mono, probably, Contract class is empty. I haven't done this, but chapter seven from the Contracts manual seems to explain how to provide your own implementation.
From the Contract class docs:
Important
You must install a Visual Studio add-in to enforce contracts. The Code
Contracts Premium Edition add-in lets you specify static and run-time
checking of code contracts on the project Properties page. If you do
not enable run-time checking, contracts such as the Contract.Ensures
method will not throw exceptions during run time if a contract is
violated. The Visual Studio add-in does not ship with Visual Studio
2010 or the Windows SDK.
With a message like this it is usually helpful to specify exactly what you have done.
For example, you do not mention in the original message if you have installed the VS Addon, nor that you have enabled it under your project properties, or that you are actually running in debug vs release mode, etc.
Re Contract.Requires vs Contract.Requires<Exception>
Contract.Requires is recommended.
According to the manual
If your code must throw a particular exception on failure of a
particular precondition, you can use the generic overloaded form
below. (Please read Section 5.1 before committing to this form in your
code. You cannot use Requires < Exn <Exn>> without running the contract tools
on all builds. If you do, you will get a runtime failure everytime.)
Please clarify, is the Code Contracts is similar to FxCop and StyleCop?
As per the online references, we need to add Codes for implementing the code contract conditions inside the function of existing code.
public void Initialize(string name, int id)
{
Contract.Requires(!string.IsNullOrEmpty(name));
Contract.Requires(id > 0);
Contract.Ensures(Name == name);
//Do some work
}
Usually in FxCop, the code we want to check will be in separate Dll and the Class library which includes the rules to check will be in separate dll.
Likewise whether we can create separate class library for Code contract to rule the existing code?
Please confirm..
disclaimer: you'd better take their current docs and read them through, write down the features and then compare them. What I wrote below is some facts I remembered long time ago about their core functionalities and I can't guarantee you that they are not outdated and now-wrong. For example, someone could write some complex&heavy rules for FxCop that behave as Contracts do. This is why I'm marking it as community-wiki. Please correct me if I'm wrong anywhere.
No they are not similar, although they share common target: help you find bugs.
FxCop is a "static analyzer", which inspects your code and tries to find "bad patterns". You will not see any FxCop rules/effects during runtime. FxCop has a set of "rules" that will be used during inspection and it reports to you whenever it finds a rule to be broken. Rules can be very easy and nitpicking like you must initialize every variable or you must name classes with uppercase or complex ones like you shouldn't have more than one loop in a method. Some rules are available by the standard installation, and you can expand the ruleset with your own rules.
CodeContracts is two-sided. At the most basic level, it is a set of helper methods, like throw if argument 'foo' is null. At runtime, when someone passes a null, it will throw. Just that simple. However, if you use those helper methods correctly and widely in your code, you will be able to run an additional static analyzer. It will scan your code, find all usages of those helper methods, and will try to automatically detect any places where their contracts are not satisfied. So, with the "argument is null" example, it will try to find all usages of that function, check who calls it with what args, it will try to deduce (prove) if that arg can be null at all anytime, and will warn you if it finds such case. There are more types of such validators other than just not-null, but you can't add/write your own. I mean, you could add more such helper validators, but the static analyzer wouldn't pick them up (it's too hard to write a general theorem prover for any rule).
CodeContracts is more powerful in its analyses than FxCop, but limited in diversity and scope. CodeContracts cannot check the structure of the code: it will not check the number of loops, code complexity, names of methods, code hierarchy, etc. It can only attempt to prove/disprove some contracts (runtime requirements) of some methods/interfaces. FxCop on the other hand can inspect your code, style, structure, etc, but it will not "prove" or "deduce" anything - it will just check for some bad patterns defined by rules.
While FxCop is used to verify some code-style or typical perfomance issues,
Code Contracts influences your code design, so it aims to achieve higher level goals. It's a .NET implementation attempt of contract programming methodology used in Eiffel language. Methodology says, that every type will behave correctly (performing its postconditions and invariants), only if it will have input according to required preconditions.
You should describe your types preconditions, invariants and postconditions with use of library helper methods and attributes (Contract.Requires, etc.) and Code Contracts static analizer will be able to detect their failures during compilation.
(Last time I looked at it, tool was rather slow and hard to use. Seems, that it haven't been completed by microsoft research team. Fortunately, few days ago a new version of it have been released with bug-fixes for async-await as well as VS2015 support.)
At compile time, how can I check if a data type (and or value) is being used within a method.
I'm attempting to build a living architecture that supports plugins.
I want the compiler to throw an error if an event is not being raised within the plugin.
I'm using VS2015 Preview.
Any suggestions?
This kind of validation is possible to implement using PostSharp. It is not trivial but easier than using Mono.Cecil. SyntaxTreeVisitor and ISyntaxReflectionService is a good foundation for implementing the analysis algorithm which has to be invoked from Aspect.CompileTimeValidate.
Roslyn must be mentioned as well. It allows you to "extend" C# (or VisualBasic) compiler with custom diagnostics and it is very well integrated with VS2015.
Disclaimer: I'm PostSharp developer.
I don't think you can make the compiler throw that error for you. You might be able to introduce an extra build step that executes a C# console app that checks (using reflection) what you want.
I got a pretty common scenario, namely a self implemented ILogger interface. It contains several methods like _logger.Debug("Some stuff") and so on. The implementation is provided by a LoggingService, and used in classes the normal way.
Now I have a question regarding performance, I am writing for Windows Phone 7, and because of the limited power of these devices, little things may matter.
I do not want to:
Include a precompiler directive on each line, like #IF DEBUG
Use a condition like log4net e.g. _logger.DebugEnabled
The way I see it, in the release version, I just return NullLoggers, which contain an empty implementation of the interface, doing nothing.
The question is: Does the compiler recognize such things (may be hard, he can't know on compile time which logger I assign). Is there any way to give .NET a hint for that?
The reason for my question, I know entering an empty function will not cause a big delay, no problem there. But there are a lot of strings in the source code of my application, and if they are never used, they do not really need to be part of my application...
Or am I overthinking a tiny problem (perhaps the "string - code" ratio just looks awful in my code editor, and its no big deal anyway)..
Thanks for tips,
Chris
Use the Conditional attribute:
[Conditional("DEBUG")]
public void Debug(string message) { /* ... */ }
The compiler will remove all calls to this method for any build configurations that don't match the string in the conditional attribute. Note that this attribute is applied to the method not the call site. Also note that it is the call site instruction that is removed, not the method itself.
It is probably a very small concern to have logging code in your application that does not "run". The overhead of the "null" logger or conditionals is likely to be very small in the scheme of things. The strings will incur memory overhead which could be worrying for a constrained device, but as it is WP7 the minimum specs are not that constrained in reality.
I understand that logging code looks fugly though. :)
If you really want to strip that logging code out...
In .Net you can use the ConditionalAttribute to mark methods for conditional compilation. You could leverage this feature to ensure that all logging calls are removed from compilation for specified build configurations. As long as methods that you have decorated with the conditional attributes follows a few rules, the compiler will literally strip the call chain out.
However, if you wanted to use this approach then you would have to forgo your interface design as the conditional attribute cannot be applied to interface members, and you cannot implement interfaces with conditional members.