2

I have a node class that basically consists of a parent property and a list of childs. There's an AddChild method which shouldn't receive null as an argument. Users shall not add a null child.

But the parent property must allow null values (a root node has a null parent).

The question is "How to forbid users to add null children at compile-time?". I know I could add a NullArgumentException, but that is not what I need.

Another way around would be creating a List that doesn't accept null items (compile-time).

Code:

class Node
{
    public Node Parent { get; set; }
    private List<Node> Children = new List<Node>();

    public void AddChild<Maybe a generics solution?>(Node???? Child) where ????
    {
        //I don't want to add (if Child == null) Throw new ArgumentNullException();
        Children.Add(Child);
    } 
}
Daniel Möller
  • 84,878
  • 18
  • 192
  • 214
  • 1
    C# does not support this feature. – SLaks Jan 24 '14 at 19:29
  • What is the reasoning behind the fact that you don't want to have an if-condition inside your AddChild method checking if a null parameter has been passed? – Paweł Bejger Jan 24 '14 at 19:30
  • Closely related to: http://stackoverflow.com/questions/6365459/create-non-nullable-type-in-c-sharp – Peter Rasmussen Jan 24 '14 at 19:31
  • Personally I don't see what's wrong with throwing an Exception. If somebody is calling `AddChild` and getting a bunch of exceptions, that will make them think twice about sending you a null `Node` in the first place. – Cᴏʀʏ Jan 24 '14 at 19:35
  • I would read [Eric Lippert's blog post](http://blog.coverity.com/2013/11/20/c-non-nullable-reference-types/#.UuK_ctgo7RY) about why there aren't non-nullable types in C#. It's not currently a feature of C# but a very interesting read. – Adam Modlin Jan 24 '14 at 19:31

2 Answers2

3

This is a "shortcoming" of C# language design. There is a way to make a value type (struct T) be nullable (Nullable<T>) but there is no way to specify a reference type argument should not be null. The best you can do is check for null and throw an ArgumentNullException (or use code contracts as pnewhook suggests).

See MailmanOdd's answer for a link to Eric Lippert's blog post on the topic.

Timothy Shields
  • 75,459
  • 18
  • 120
  • 173
  • That's a good idea, trying to invert things and make the node a struct, while `parent` would be `Nullable`...I'll think of the consequences.... – Daniel Möller Jan 24 '14 at 19:33
  • @Daniel That won't work unfortunately. A struct is a value type, so you *can't* have one node "point to" another. You're on the right track using a class, but you'll have to live with the manual null check. – Timothy Shields Jan 24 '14 at 19:35
2

You can't disallow null arguments, the best you can do is raise an error when an argument pre-condition is violated. Since you don't want to throw ArgumentNullException if child is null, I'd recommend code contracts.

Contract.Requires( x != null );

It's a little more terse and you get the added option of statically checking at build time if your precondition is violated.

pnewhook
  • 4,048
  • 2
  • 31
  • 49
  • Sorry....I don't understand what you mean by "statically checking at build time"... – Daniel Möller Jan 24 '14 at 19:49
  • With a little bit of tooling for Visual Studio, you can run a check as part of your build to see if any code calls a method in a way that violates a contract. It's 'static' in that the code isn't actually run, just evaluated. – pnewhook Jan 24 '14 at 20:26