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.
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.