1

I know there is optional parameter in .NET, but is there a way to force .NET to throw an exception if a parameter is null?

That way I do not have to do parameter null checks on my methods, which clutter the code.

Or is there any other way to enforce non-null parameters on my method signature?, using attribute perhaps?

Community
  • 1
  • 1
Rosdi Kasim
  • 24,267
  • 23
  • 130
  • 154
  • Or you could pass non-nullable value types. – Frédéric Hamidi Dec 03 '13 at 10:06
  • 3
    If a parameter is not optional, then it's mandatory - unless there is an overload that doesn't include that parameter then you simply cannot call that method unless you pass a value for that particular parameter. Your definition of "mandatory" seems to be "must not be null" - which is not the same thing, since there is no reason you shouldn't be allowed to pass null as a parameter if null happens to be an accepted value for that parameter. – BoltClock Dec 03 '13 at 10:08
  • 1
    Yes, your definition of mandatory is somewhat odd and is certainly not the opposite of optional parameters. In fact it seems completely unrelated to optional parameters. – David Heffernan Dec 03 '13 at 10:09
  • 1
    And in addition - an optional parameter could still accept a null value, and that would not be "mandatory" according to your definition anymore, so indeed what you're looking for has nothing to do with optional parameters. – BoltClock Dec 03 '13 at 10:11
  • 1
    There is no support for this in C#. In the future they *could* add a feature like `public void Add([NotNull] Customer c) { ... }` or `public void Add(Customer c != null) { ... }` or some better syntax. That would/could then be compiled into the same IL as `public void Add(Customer c) { if (c == null) { throw new ArgumentNullException("c"); } ... }`. However, I don't think they are going to introduce that. You will have to insert the check manually. You can extract to a method as in Moo-Juice's answer, or use Code Contracts as in Ralf de Kleine's answer. – Jeppe Stig Nielsen Dec 03 '13 at 10:25
  • You can use some generic tricks to this check; this will make your code compilcated. I think the best approach for this problem is Design by contract. – Bassam Alugili Dec 03 '13 at 10:54
  • BoltClock, David I understand your point.. and I agree.. however I will leave the title as is because I think that will be the first people search in google. – Rosdi Kasim Dec 03 '13 at 13:31

5 Answers5

2

You could use Code Contracts.

Ref: Microsoft

Example from link:

void IArray.Insert(int index, Object value)
{
    Contract.Requires(index >= 0);
    Contract.Requires(index <= ((IArray)this).Count);  // For inserting immediately after the end.
    Contract.Ensures(((IArray)this).Count == Contract.OldValue(((IArray)this).Count) + 1);
}
Ralf de Kleine
  • 11,464
  • 5
  • 45
  • 87
1

There's nothing out of the box, but I use an extension method to do this:

public static class GenericExtensions
{
    /// <summary>
    /// Throws an ArgumentNullException if "this" value is default(T)
    /// </summary>
    /// <typeparam name="T">(Inferred) "this" type</typeparam>
    /// <param name="self">"this" value</param>
    /// <param name="variableName">Name of the variable</param>
    /// <returns>"this" value</returns>
    /// <exception cref="System.ArgumentException">Thrown if "this" value is default(T)</exception>
    public static T ThrowIfDefault<T>(this T self, string variableName)
    {
        if (EqualityComparer<T>.Default.Equals(self, default(T)))
            throw new ArgumentException(string.Format("'{0}' cannot be default(T)", variableName));
        return self;
    }   // eo ThrowIfDefault<T>    
}

Usage:

public void SomeFunc(string value)
{
    value.ThrowIfDefault("value");
}

public void MyFunc(Guid guid)
{
    guid.ThrowIfDefault("guid");
}

It's also useful in class constructors as it returns the value also:

public class A
{
}

public class B
{
    private readonly A _a;

    public B(A a)
    {
        _a = a.ThrowIfDefault("a");
    }
}

It is also trivial to write one for strings that ensure that not only is it non-null, but that it also has a length,.

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
  • Why did you choose an example with a default value of a non-nullable type, the empty GUID, when he asked about `null`? I do know your method will work for other types too. – Jeppe Stig Nielsen Dec 03 '13 at 10:10
  • @JeppeStigNielsen, good point. Have added some additional examples. – Moo-Juice Dec 03 '13 at 10:13
  • I think you should add `where T : class` – Ilya Ivanov Dec 03 '13 at 10:18
  • 1
    If he used `where T : class`, it would limit the scope to tests for null references only. In that case `EqualityComparer.Default.Equals(self, default(T))` should be simplified to `self == null`. (We assume that no-one overrides `Equals` in a way that makes an instance "equal to" null. That would probably break other things in .NET too.) – Jeppe Stig Nielsen Dec 03 '13 at 10:34
  • Hey I could use this.. less verbose than doing `if(param == null)` all over the place. – Rosdi Kasim Dec 03 '13 at 13:37
1

Probably, the solution is the combination of Code Contracts (which are very helpful while debugging) and direct parameter check for throwing exception in release:

void MyMethodWithNotNullValue(Object value) {
  // Contract failure allow you to see the stack, 
  // inspect local variables' values,
  // start debugger etc.
  Contract.Requires(!Object.ReferenceEquals(null, value));

  // Unfortunately, contracts can be switched off (usually in release), 
  // so we have to check "value" manually as well
  if (Object.RefrenceEquals(null, value))
    throw new ArgumentNullException("value", "You can't set null to value because...");

  ...
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • So if Contract can be switch off it has no effect? As if the checks are not there? I have no problem with that since we have control over the deployment process. – Rosdi Kasim Dec 03 '13 at 13:39
  • When compiling (usually building release) contracts as well as assertions (Debug.Assert) can be switched off (see "Perform Runtime Contract Checking"). Sure, you don't have to switch off contracts in release, but you can do this; that's why I use double check – Dmitry Bychenko Dec 03 '13 at 13:51
0

You could also look into Aspect oriented programming

This gives you a before and after method execution.

public class LogAspect : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        Console.WriteLine(Environment.NewLine);

        Console.WriteLine("Entering [ {0} ] ...", args.Method);

        base.OnEntry(args);
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        Console.WriteLine("Leaving [ {0} ] ...", args.Method);

        base.OnExit(args);
    }
}
Ralf de Kleine
  • 11,464
  • 5
  • 45
  • 87
0

.net MVC Application when u create a Model of particular Variable at that time you can use like this ............................

**[Required(ErrorMessage = "Department Required")]

    public string Department { get; set; }**

so when user is forget to add Department at that time it will through exception in view u have to also like that ..................

@Html.ValidationMessageFor(m => m.Department) in view you can write like this