Skip to content
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

NullableContextOptions and nullable generic type #2309

Closed
pengweiqhca opened this issue Mar 7, 2019 · 12 comments
Closed

NullableContextOptions and nullable generic type #2309

pengweiqhca opened this issue Mar 7, 2019 · 12 comments

Comments

@pengweiqhca
Copy link

<NullableContextOptions>enable</NullableContextOptions>
static void Test<T>(out T? value) //Error!
{
    value = default;
}
@yaakov-h
Copy link
Member

yaakov-h commented Mar 7, 2019

Yes, and?

error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint.

The error message tells you exactly what's wrong and how to fix it.

T? on a reference type is compiled to T but the compiler can emit warnings based on flow analysis.

T? on a value type is compiled to Nullable<T>.

The two cannot co-exist, so you have to specify either where T : class or where T : struct.

@Joe4evr
Copy link
Contributor

Joe4evr commented Mar 7, 2019

That said, you should see an additional attribute (along the lines of [MaybeNull], I forget the exact name) specifically for this case that will inform the flow analysis at the callsite that if T is a reference-type, it has to be checked for null before it can be dereferenced.

@TheUnlocked
Copy link

TheUnlocked commented Mar 7, 2019

It could be useful to have the language automatically generate an overload for both cases when possible, though you'd probably want an additional attribute or keyword for that.

@pengweiqhca
Copy link
Author

pengweiqhca commented Mar 8, 2019

I want CanBeNull generic type, both value types and reference types. Or can be add overload by where T : class and where T : struct

@hez2010
Copy link

hez2010 commented Mar 25, 2019

@yaakov-h
I think compiling T? on a reference type to T is incomplete for C# type system, and it causes inconsistance between value type and reference type.

In my opinion T? should be always compiled to Nullable<T>, or at least there should be an option for users to opt-in such "strict nullable context".

@yaakov-h
Copy link
Member

@hez2010 Nullable<T> is declared as public struct Nullable<T> where T : struct. It is impossible for T to be a reference type.

@hez2010
Copy link

hez2010 commented Mar 26, 2019

@yaakov-h
Hmmmmm.... why not add a public class Nullable<T> where T : class for nullable reference type?
In my option, simply treat all those nullable types as Monads Nullable<T> is okay (for competible consideration, users need to opt-in this feature manually.)

@yaakov-h
Copy link
Member

@hez2010 see also: #2361 (comment)

@Joe4evr
Copy link
Contributor

Joe4evr commented Mar 26, 2019

@hez2010 See also the by-now 4 year old decision that wrapper structs are a no-go:

the most damning objection to the wrapper structs is probably the degree to which they would hamper interoperation between the different variations of a type. For instance, the conversion from string! to string and on to string? wouldn't be a reference conversion at runtime. Hence, IEnumerable<string!> wouldn't convert to IEnumerable<string>, despite covariance.

@hez2010
Copy link

hez2010 commented Apr 9, 2019

I think what we really need is to separate types to nullable types and non-nullable types, but not the fake nullable type with a compile-time check.

If Nullable<T> has been taken up by struct, you can also introduce ReferenceNullable<T> where T : class for reference types.

The current nullable reference type implementation only does compile-time check and the only benefit is to prevent nullable types' spread in your own codes, which didn't solve the actual problem.

I think breaking changes are must for it, otherwise the nullable reference type won't play the role it deserves.

And for competible consideration, the feature can be designed to a feature that needs to be opt-in manually by users.

@jcouv
Copy link
Member

jcouv commented May 6, 2019

Relates to #2194

@YairHalberstadt
Copy link
Contributor

Closing as implemented in C# 9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants