Discussion: Should we allow struct types to overload cast operator to their nullable counterpart in user code? #1846
Replies: 4 comments
-
Is there a use case other than improved handling of nullability of reference types? Because I don't think it makes sense to add a feature that would be effectively obsoleted by nullable reference types (#36, currently planned for C# 8.0). |
Beta Was this translation helpful? Give feedback.
-
I must admit, the discussion about nullable reference types was unknown to me until now and is quite big so I haven't thoroughly examined it. For the most part I would focus on this section:
If I read that correctly, the compiler will allow user code to skip the |
Beta Was this translation helpful? Give feedback.
-
Minor note: allowing this overload could permit to implicitly cast public readonly struct IntPtr // ...snip...
{
public static readonly IntPtr Zero;
// ...snip...
public static implicit operator IntPtr(IntPtr? value)
=> value ?? Zero;
} Allowing the following code to compile: // Cannot convert null to 'IntPtr' because it is a non-nullable value type. csharp(CS0037)
IntPtr ptr = null; |
Beta Was this translation helpful? Give feedback.
-
It would have, had we not explicitly rejected it as too breaking of a change. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I am creating this suggestion in relation to the following issue. I came up to this point trying to implement a use-case I've asked about in Stackoverflow
In the particular use case I was creating a
Nullsafe<T>
struct type that would be analogical to theSystem.Nullable<T>
type, but the underlying type is instead a reference type. Long story short, I wanted to reduce unnecessary code when expressions likeNullable<Nullsafe<T>>
are encountered. Typically, I should useGetValueOrDefault()
if I want to pass an instance ofNullable<Nullsafe<T>>
to a method expecting justNullsafe<T>
.So, I attempted add an implicit cast, which the compiler did not allow me to.
public static implicit operator Nullsafe<T>(Nullable<Nullsafe<T>> nv) => nv.GetValueOrDefault();
Below is the error thrown by the compiler that lead to creating this thread:
The message is not really correct, as it is a result of intentional erasure of the nullable type done by the compiler.
By opening this issue, I'd like to see whether there is a point of allowing developers to define cast operators to the nullable counterparts of their own user-defined struct types.
I believe in use-cases like mine, that would be beneficial, as any value of
Nullable<Nullsafe<T>>
would be semantically identical to the underlyingNullsafe<T>
value. Allowing a cast fromNullable
would simplify some cases, as for instance methods accepting aNullsafe<T>
as arguments would implicitly accept instance ofT
,Nullsafe<T>
andNullable<Nullsafe<T>>
if the appropriate cast operators are defined.On the other hand, the
Nullable<T>
type itself is, without any doubt, designed to not implicitly disclose its underlying value. In case this behaviour should be enforced to all user-defined types, it would be better to have a more-direct error message, such as "User-defined operators cannot take an object of the enclosing type and convert to an object of the enclosing type or a nullable wrapper of the enclosing struct type". The point is that the message must specifically address the case where nullable wrappers cannot be used as operands.Beta Was this translation helpful? Give feedback.
All reactions