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

Proposal: target typing for "default" in C# #13255

Closed
jcouv opened this issue Aug 18, 2016 · 15 comments
Closed

Proposal: target typing for "default" in C# #13255

jcouv opened this issue Aug 18, 2016 · 15 comments
Assignees

Comments

@jcouv
Copy link
Member

jcouv commented Aug 18, 2016

The default keyword currently requires an explicit type.
For instance, one has to write default(ImmutableArray<string>).
But the type could be omitted in most cases, resulting in simpler code: default.

You would be allowed to write:

  1. M(default);,
  2. x = default;, where x is known to have type ImmutableArray<string>.

Note this feature is already available in VB, as you can use the Nothing keyword for the default value (both for class and struct types).
If we wanted to follow the VB approach, the proposal could extend to allowing null as default value for value types as well, such as ImmutableArray<string> x = null;.

FYI @dotnet/roslyn-compiler

Update: As @svick pointed out, proposal #35 to allow type inference in constructions (new ()), but @gafter clarified this would have different meaning.

Update: We should allow:

  1. const int x = default; (using target-typed default for constant)
  2. object x = default; (using target-typed default for reference type)
@svick
Copy link
Contributor

svick commented Aug 18, 2016

If we wanted to follow the VB approach, the proposal could extend to allowing null as default value for value types as well, such as ImmutableArray<string> x = null;.

I really don't like this part of the proposal. null should be reserved only for nullable types.

Also, I think it would be a breaking change, at least as long as C# sticks with the "methods in derived class have precedence over methods from base class" principle in overload resolution.

@svick
Copy link
Contributor

svick commented Aug 18, 2016

Also, #35 is closely related. With that, the code would be:

ImmutableArray<string> x = new();

@jcouv
Copy link
Member Author

jcouv commented Aug 18, 2016

@svick Thanks for pointing out #35. That would definitely solve this problem (and more).

@alrz
Copy link
Contributor

alrz commented Aug 19, 2016

Looks like #7737.

I prefer default over new() specially in optional arguments because it won't mind if the type is a value type or reference type,

void M(int value = default, object obj = default) { .. }
// compared to
void M(int value = new(), object obj = null) { .. }

I'm not against #35 but, in my opinion, it is not a replacement for default.

@DavidArno
Copy link

I'd agree with @alrz that #35 is a distraction here and that this proposal is a useful one (where as I don't believe #35 is useful).

What use is SomeType x = new(); when the language already supports var x = new SomeType();, and what use is F(new()) when F is well written and specifies that parameter via an interface?

Whereas, for example, being able to rewrite:

TR F<T, TR>(T p) => (some expression of p) ? default(TR) : (some val of TR);

as

TR F<T, TR>(T p) => (some expression of p) ? default : (some val of TR);

would be a nice noise-reducing addition to the language.

@alrz
Copy link
Contributor

alrz commented Aug 19, 2016

@DavidArno Not to distract, but I think #35 comes in handy in field initialization where we don't have var. My point is that these are different use cases and new () doesn't mean anything near default, for example, for a generic type you can't use new () unless it is constrained to have a default ctor, while default is applicable to all types.

@gafter
Copy link
Member

gafter commented Aug 19, 2016

I think these two proposals (#13225 and #35) are complimentary, especially as we hope to add the ability to declare a no-args constructor in struct types in the future.

@AlgorithmsAreCool
Copy link

...especially as we hope to add the ability to declare a no-args constructor in struct types in the future.

@gafter
My eyebrow raised itself upon reading this, are there any details details available publicly?

@orthoxerox
Copy link
Contributor

@AlgorithmsAreCool IIRC this was already prototyped once, but some internal CLR subsystems relied on the assumption that all new()ed structures were identical blobs of zeroes.

@svick
Copy link
Contributor

svick commented Aug 20, 2016

@AlgorithmsAreCool @orthoxerox The issue for the revert of that prototype is #1029.

@HaloFour
Copy link

I agree with @svick that null should not be considered the same as default when it comes to value types. Otherwise, I think allowing the use of default as shorthand for default(T) is nice when the compiler already knows what the type of the target expression is supposed to be.

@DavidArno
Copy link

@gafter

...especially as we hope to add the ability to declare a no-args constructor in struct types in the future

Oh my. That is incredible news. The inability to declare a no-args constructor in struct types in my single biggest complaint about them, eg with the need to include an unused parameter (and then suppress CA1801) when declaring a private constructor that should have no parameters).

@jcouv jcouv changed the title Proposal: type inference for "default" in C# Proposal: target typing for "default" in C# Aug 22, 2016
@jcouv jcouv self-assigned this Aug 22, 2016
@VSadov
Copy link
Member

VSadov commented Aug 23, 2016

I like the proposal.

Make sure that "default" does not have default type. :-)

VB Nothing defaults to Object. There are reasons for that, but in a case of C# it would only introduce unnecessary complexities.

@VSadov
Copy link
Member

VSadov commented Aug 23, 2016

It would indeed compliment the default struct constructors.

Default struct constructors and instance field initializers were at production stage in C#6.0 but ran into bugs in various runtimes. Most prominently the issue in Activator.CreateInstance which resulted in a broken generic new T().
The risk/benefit was not in the favor of the feature at the time, so we had to pull them out in #1029

@jcouv
Copy link
Member Author

jcouv commented Sep 1, 2016

I'll close this proposal, as it is a duplicate of #7737 (as @alrz pointed out).

@jcouv jcouv closed this as completed Sep 1, 2016
@jcouv jcouv added Resolution-Duplicate The described behavior is tracked in another issue 1 - Planning labels Sep 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests