Creating an immutable value object in C# - Part IV - A class with a special value - Luca Bolognese

Creating an immutable value object in C# - Part IV - A class with a special value

Luca -

☕ 2 min. read

Other posts:

  • Part I - Using a class

    A good thing about the struct im­ple­men­ta­tion was the in­tro­duc­tion of an ex­plicit special val­ue’ in­stead of null’. I per­son­ally like do­ing that be­cause it forces me to think about what are the spe­cial val­ues in my do­main in­stead of blindly rely on null and its se­man­tics. Plus, it also works where null breaks down, when there are mul­ti­ple spe­cial val­ues.

    Having ex­plicit spe­cial val­ues is ob­vi­ously not re­lated to structs in any way. You can use the same pat­tern with classes as well, but you have to man­age null’ val­ues that can en­ter your API. Here is how I did it for the DateSpan class.

    First I de­fined an util­ity func­tion to man­age null val­ues:

    public static void CheckNull<T>(T t) {
        if (t == null)
            throw new ArgumentNullException();
    }

    Then I had to check my null pre­con­di­tion for each pa­ra­me­ter of my API. I.E.

    public DateSpan Intersect(DateSpan other) {
        Utils.CheckNull(other);
        ...
    }

    Most im­por­tantly I now have to check for null in Equals’ and ==’:

    public override bool Equals(object obj) {
        // Interesting choice, null is not valid in this domain
    

Utils.CheckNull(obj); if (this.GetType() != obj.Get­Type()) re­turn false; DateSpan other = obj as DateSpan; re­turn other.End == End && other.Start == Start; }

<pre class="code"><span style="color:rgb(0,0,255);">public</span> <span style="color:rgb(0,0,255);">static</span> <span style="color:rgb(43,145,175);">Boolean</span> <span style="color:rgb(0,0,255);">operator</span> ==(<span style="color:rgb(43,145,175);">DateSpan</span> v1, <span style="color:rgb(43,145,175);">DateSpan</span> v2) {
    <span style="color:rgb(43,145,175);">Utils</span>.CheckNull(v1);
    <span style="color:rgb(43,145,175);">Utils</span>.CheckNull(v2);
    <span style="color:rgb(0,0,255);">return</span> (v1.Equals(v2));
}</pre>

So now we have an immutable value object, represented as a class, with checks for nulls and a special value (not shown above because it is essentially the same as for structs). So, does this work?

It does, but it is cumbersome to write. And if it is too cumbersome, I already know that I'm not going to use it. I might start doing it, but I would soon give up. Are there ways to ease the pain?

One way would be to use snippets to help in writing the code. Snippets in this case have a couple of problems:

  * It is not easy to &#8216;snippify' the logic inside &#8216;Equals', &#8216;GetHashcode' and such
  * It makes easy to write the code, but still it is hard to read it and maintain it

In the next post we'll look at a better solution.
6 Comments

Comments

David V. Corbin

2007-12-28T18:53:36Z

Why are you ignoring the power of Guidance Automation to create all of the classes?????

Shouldn't you simply return false for equality if the other value is null instead of throwing?  

David: because I barely know what it is ;-)
Anyhow, I think there is a simpler solution. I'll post it later.
Onovotny: yes, that is usually the recommended way. In my case, I don't want for these objects to ever be null. If one of them is null, it means that there is something wrong in my app and I want to know it. Hence the exception.

Charlie Calvert's Community Bl

2008-01-03T02:13:41Z

Welcome to the thirty-eighth Community Convergence. These posts are designed to keep you in touch with

Tales from the Evil Empire

2008-01-16T18:36:55Z

For some reason, there's been a lot of buzz lately around immutability in C#. If you're interested in

0 Webmentions

These are webmentions via the IndieWeb and webmention.io.