8
\$\begingroup\$

Looking forward for C# Nullable Reference Types in C# 8.0. I do not like to use the preview implementation in a production code though, so just went with these simple helper classes intending them to be upgraded to new syntax by search and replace when time comes.

Usage sample:

static void Main(string[] args)
{
    var johnk = new FullName("John", "F.", "Kennedy");
    var johnd = new FullName("John", null, "Do");
    var johnn = new FullName("John", null, null); // throws
}

Where business class is:

class FullName
{     
    public FullName(Some<string> first, Option<string> middle, Some<string> last) =>
        (First, Middle, Last) = (first, middle, last);

    public string First { get; }
    public string Middle { get; }
    public string Last { get; }
}

Library code:

[DebuggerStepThrough]
struct Some<T> where T : class
{
    public static implicit operator Some<T>(T value) => 
        new Some<T>(value ?? throw new ArgumentNullException());

    public static implicit operator T(Some<T> some) => 
        some.Value ?? throw new ArgumentNullException();

    Some(T value) => Value = value; 
    T Value { get; }
}

And

[DebuggerStepThrough]
struct Option<T> where T : class
{
    public static implicit operator Option<T>(T value) => 
        new Option<T>(value);

    public static implicit operator T(Option<T> some) => 
        some.Value;

    Option(T value) => Value = value;
    T Value { get; }
}

Nothing fancy, just does the job and it would be easy to upgrade syntax…

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I would decorate both the constructor and Value property with an explicit private access modifier. \$\endgroup\$ – Jesse C. Slicer Jun 18 '18 at 19:47
  • 2
    \$\begingroup\$ It feels like I learn something new about C# syntax every time I read your questions. :) I had no idea you can use tuples to inline constructor implementation. \$\endgroup\$ – Nikita B Jun 19 '18 at 11:17
8
\$\begingroup\$

There are some disadvantanges about this solution. You not only loose the argument-name inside the exception but if you are using ReSharper then you won't be able to quick-fix this in future.

Thus I think it's not necessary to create such helpers because as soon as the new feature is there, ReSharper will probably have nice quick-fix for that so it'll turn all if(foo == null) throw new ArgumentException(..) into the new syntax. I doubt ReSharper will be able to quick-fix this.

Besides if you properly decorate your code with the [NotNull] and [CanBeNull] attributes, you are half-way safe. Since I started using them, It's been ages that I last saw a NullReferenceExcepiton or ArgumentNullExcepiton.


I also find ReSharper's naming convention more appealing. This means

  • Some becomes NotNull and
  • Option becomes CanBeNull
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.