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

Created on 18 Aug 2016  路  15Comments  路  Source: dotnet/roslyn

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)
1 - Planning Area-Language Design Feature Request Language-C# Resolution-Duplicate

Most helpful comment

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.

All 15 comments

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.

Also, https://github.com/dotnet/roslyn/issues/35 is closely related. With that, the code would be:

c# ImmutableArray<string> x = new();

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

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.

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.

@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.

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.

...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?

@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.

@AlgorithmsAreCool @orthoxerox The issue for the revert of that prototype is https://github.com/dotnet/roslyn/issues/1029.

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.

@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).

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.

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 https://github.com/dotnet/roslyn/issues/1029

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

Was this page helpful?
0 / 5 - 0 ratings