-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C# should allow implicit Nullable<T> conversion if data-flow proves not-null #3317
Comments
In the current design of the nullability feature, nullability analysis only affects warnings, it doesn't affect the semantics of the language. The |
Sorry, I figured it could apply to VB and C# equally. Can you move it? The lifting of methods is rather radical, esp. with the chicken and egg problem you mention. Let's forget that. The first part is doable, though. If you think about it, it's only affecting warnings/errors not the understanding of the language. This time it would be about removing an error rather than adding one. During the first pass, the compiler sees an implicit conversion from Later after data-flow it can decide whether:
I'm sure the error is emitted rather early in current code, but that's an implementation detail: maybe you can move it to a later stage? |
Some of this is discussed here: #1865 |
Note: i would only want this if provably safe (since it changes codegen). if this was done, i should never get a null-ref exception with the assignment/use of the variable. |
As has mentioned in #1865, we considered this and explicitly decided against it. Now that C# 8 has shipped, changing this would be a breaking change (and would have been a breaking change at the time, as it could affect overload resolution). |
@333fred How is allowing an implicit cast that was previously forbidden a breaking change? It doesn't change the behavior of any program that was valid before the change. |
public class C {
public void M(long? l) {}
public void M(int i) {}
void M2(int? i)
{
if (i != null)
M(i);
}
} This program is valid today. It would become ambiguous with this change and fail to compile. |
@333fred It's a good point. |
No. Overload resolution does not try to guess which implicit conversion would be better, it only attempts to find the most specific method. This is only the tip of the iceberg here, as well. There are scenarios where this can change lambda inference, type parameter inference, and others. This is really not a change that we can consider. |
Well if it gets so complex I guess it's not really worth it, feel free to close this. |
Version Used: Visual Studio, C# Tools 3.5-beta4
Steps to Reproduce:
Implicit conversion of
Nullable<T>
toT
has always been forbidden by C#, because this conversion can fail if the nullable is actually null.It can be explicitely done by either casting
y = (T)x
or using the value propertyy = x.Value
. Both throw ifx
doesn't hold a value.Nowadays C# 8 has nullable data-flow analysis (for nullable reference types) and we become used to going from
string?
tostring
simply by having aif
guard (or otherwise).It feels weird and is a missed productivity enhancement that the data-flow analysis is not applied to nullable value types.
I understand that the underlying type of a nullable value is different and it won't magically change thanks to a
if
, but implicit conversion should be allowed.Examples:
Expected Behavior:
These implicit conversions should be allowed by the compiler to happen, as if I wrote
y = (int)x
, as the compiler can prove they won't fail.Actual Behavior:
CS0266: Cannot implicitly convert type 'int?' to 'int'.
Bonus round: If we're being very bold, I suggest that methods of
T
be lifted toNullable<T>
whenever the data-flow indicates it's not null. That would be a nice improvement and unify the way references and value types feel when it comes to nullability.This would be ambiguous for members that are shared between
Nullable<T>
andT
. Most likely none but astruct
could have aValue
of its own.In this case I suggest the nullable takes precedence (you'll have to do
x.Value.Value
).The text was updated successfully, but these errors were encountered: