I am currently creating a struct Nullsafe<T> that would wrap a reference type (hence T:class) and behave in a similar way to the Nullable<T> struct. The point is to emulate something close to what the Option<T> in F# does.
I intend to use the type in methods which I need to take special care of nulls. For example, assume I have a reference type class Foo, and the following code:
class Bar
{
public void DoSomethingWithFoo(Nullsafe<Foo> foo);
}
Since I have created an implicit cast operator from T to Nullsafe<T>, then the below code would work fine:
Bar bar = new Bar();
Foo nullFoo = null;
bar.DoSomethingWithFoo(nullFoo);
Foo someFoo = new Foo();
bar.DoSomethingWithFoo(someFoo);
The Nullsafe<T> type is a struct (designed so on purpose, to eliminate passing any null values directly), therefore it is possible for someone to to write the below snippet:
Nullable<Nullsafe<Foo>> nullableNullsafeFoo = null;
// and later
bar.DoSomethingWithFoo(nullableNullsafeFoo);
The snippet, of cource, will not work.
So, I thought it would be a no-brainer to create a cast operator from within my Nullsafe<T> struct, which would handle nullable expressions like the above:
public static implicit operator Nullsafe<T>(Nullable<Nullsafe<T>> nv) => nv.GetValueOrDefault();
Unfortunately, this fails to compile. The compiler seems not to make a difference between the Nullsafe<T> and the Nullable<Nullsafe<T>> types, and throws at me the message:
Is the above a limitation of the compiler, or is it a purposedly intended behaviour? If so, are there any known workarounds?
error CS0555: User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type
I am using:
- Visual Studio Community 2017 v15.8.1
- .NET Sdk v2.1.400 (as shown by
dotnet --version
The project is a library multi-targeting different .NET framework versions - from net20 to netstandard2.0
Update
Is the above a limitation of the compiler, or is it a purposedly intended behaviour?
It seems this is indeed a result of the compiler stripping type information, as described by fellow user Isaac van Bakel.
If so, are there any known workarounds?
Doing as he adviced, I submitted an issue to the roslyn platform.