Search code examples
c#genericsimplicit-conversionnon-nullable

Is it possible in C# to write an implicit conversion operator for both nullable and non-nullable values?


I am trying to write an Alias class which enables me to:

int n = new Count(1);

That is, it encapsulates an int in this case as a Count, which gives some type safety and domain meaning, while it automatically converts back to the underlying type.

With non-nullable reference types, I have another issue. I cannot figure out how to handle both of these scenarios at the same time:

int someCount = new Count(1);
Count? nothing = null;
int? noCount = nothing;

This happens because I have types like this:

record Device(Count Cpu, Count? Cores); // Contrived example

Seems like the problem is I cannot overload an operator with both nullable and non-nullable version of the same type:

record Alias<T>(T Value)
{
  public static implicit operator T(Alias a) => a.Value;
  public static implicit operator T?(Alias? a) => null;
}

record Count : Alias<int> { /**/ }

The point is, if I have a null, I want it converted to null of the target type.


Solution

  • Yes, it is possible, using NotNullIfNotNullAttribute. Here's an example where SpecialString needs to be cast-able to string (and vice-versa) and needs to support both null and not-null instances:

    [return: NotNullIfNotNull(nameof(SpecialString))]
    public static implicit operator string?(SpecialString? SpecialString) =>
        SpecialString is null ? null : SpecialString.Value;
    
    [return: NotNullIfNotNull(nameof(value))]
    public static implicit operator SpecialString?(string? value) => 
        value is null ? null : new(value);
    

    For more information, see the MSDN article.