views:

2822

answers:

2

I want to let programmers and myself know that a method does not want null and if you do send null to it anyways, the result will not be pretty.

There is a NotNullAttribute and a CanBeNullAttribute in Lokad Shared Libraries, in the Lokad.Quality namespace.

But how does that work? I looked at the source-code of those two attributes, and it looks like this:

[AttributeUsage(
 AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate |
  AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
[NoCodeCoverage]
public sealed class NotNullAttribute : Attribute
{
}

[AttributeUsage(
 AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate |
  AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
[NoCodeCoverage]
public sealed class CanBeNullAttribute : Attribute
{
}

Two empty classes inheriting from Attribute. How are they used? Do you have to look up xml-documentation and know that it is there? Cause I tried to both make my own copy of the attribute and to use the Lokad version, but when I tried to send a null directly in, I got no message. Neither from ReSharper nor from VS. Which I kind of expected actually. But how are they used? Can I somehow make VS generate warnings for me if I try to send something that is null in there? Or is it just used in some kind of testing framework? Or?

+11  A: 

In the mid-term, "code contracts" (in 4.0) will be a better answer to this. They are available now (with academic or commercial licences), but will be more integrated in VS2010. This can provide both static analysis and runtime support.

(edit) example:

Contract.RequiresAlways( x != null );

Simple as that... the code contracts engine works at the IL level, so it can analyse that and throw warnings/errors from calling code during build, or at runtime. For backwards compatibility, if you have existing validation code, you can just tell it where the sanity checking ends, and it'll do the rest:

if ( x == null ) throw new ArgumentNullException("x");
Contract.EndContractBlock();
Marc Gravell
That looked very smooth! Will it work in VS 2008 as well? What do you mean by "more integrated"?
Svish
Yes; the links I posted were for the VS2008 variant. By "more integrated", I mean that AFAIK, it is built into the IDE and runtime, rather than being a separate add-on. I haven't checked (indeed, can't) - but this *might* possibly mean it works in the Express Edition too (the add-on doesn't).
Marc Gravell
Cool. Have you tried this add-on out yet? Easy to install and to use? Is it safe to use in a Production environment? (Will other employees kill me if I add it? :P)
Svish
I just fired up my old CTP build of VS2010, but it looks like the "bits" weren't ready when the last CTP went out. Tell you what, I'll try it and find out ;-p
Marc Gravell
Looks pretty usable. You enable it by adding a reference to Microsoft.Contracts.dll, and by setting a tick in a checkbox on the "Coer Contracts" tab of project properties. The static checker is for build-time messages.
Marc Gravell
I get that "Coer Contracts" when I install that add-on? This will have to be done on all the machines that are going to use this Solution, right? How about deployment? That Microsoft.Contracts.dll isn't in .Net Framework by default?
Svish
Not until .NET 4.0, no. However, if you set to only use contracts for debug builds, you might not need to deploy it. And if you want runtime checks, I *expect* that you can just deploy the dll for the runtime support. The install is primarily for Visual Studio purposes.
Marc Gravell
But if I started to use that Microsoft.Contracts.dll, when .NET 4.0 comes out, would I need to stop referencing my "local" copy Microsoft.Contracts.dll? Or would it be more work to "port" it?
Svish
As I understand it, the classes/namespaces etc are the same - it is only the assembly that changes. So with 4.0 you simply drop the extra reference (no other changes). But since 4.0 is pre-beta...
Marc Gravell
exactly. oh well. this looks extremely interesting! so, maybe I'll end up using it. Thanks for very good tip!
Svish
+7  A: 

This can be done either with AOP, whereby an Advice verifies at run-time whether a method parameter is null and whether nulls are allowed. See PostSharp and Spring.NET for AOP.

As for ReSharper, see Annotated Framework:

We have analyzed a great share of .NET Framework Class Library, as well as NUnit Framework, and annotated it through external XML files, using a set of custom attributes from the JetBrains.Annotations namespace, specifically:

  • StringFormatMethodAttribute (for methods that take format strings as parameters)
  • InvokerParameterNameAttribute (for methods with string literal arguments that should match one of caller parameters)
  • AssertionMethodAttribute (for assertion methods)
  • AssertionConditionAttribute (for condition parameters of assertion methods)
  • TerminatesProgramAttribute (for methods that terminate control flow)
  • CanBeNullAttribute (for values that can be null)
  • NotNullAttribute (for values that can not be null)
Anton Gogolev