3.4 KiB
C# Language Design Meeting for Apr 27th, 2022
Agenda
Quote of the Day
- "I don't like broccoli, don't make me eat it"
Discussion
Default parameter values in lambdas
https://github.com/dotnet/csharplang/issues/6051
In another iteration on lambdas, we looked at a gap that lambdas cannot expression, but local functions can: default parameter values.
There are two schools of thought on this feature, which differ by whether we generate custom delegate types for these lambdas or whether
we just use Action
/Func
and require runtime introspection of the delegate instance to determine default parameters. The former feature
will allow compile-time usage of the default parameter values, while the latter would mean that the main use case would be introspection
features, such as reflection or source-generators.
This latter proposal is interesting, but we think it's likely the wrong approach. A feature that can only be observed via reflection or source generation doesn't seem like it integrates well with the rest of C#, and if we ever want to change it in the future the breaking change would likely be quite painful. There is, however, one interesting case that was enabled with C# 10:
var m = M; // Infers Action<int>
m(); // Error: no value provided for arg0
void M(int i = 1) {}
This case doesn't generate a custom delegate type, and compiles today. We think that this isn't great behavior, and that we should change
it in C# 11, before var
for method groups has time to hugely penetrate large codebases.
We also thought about how strict we should be on matching default parameter values. For example, should this code be an error:
var x = (int i = 1) => {};
x = (int i = 2) => {}; // Reassigned with a different underlying default.
x(); // What would this pass for i?
We again have precedent with method groups, but with a slight difference: method groups converted to delegates are one possible way to call such methods. It is conceivable that there is intentionally a different default value for directly calling a method vs calling it via some delegate type, or the method could come from assembly that the user doesn't control. Lambdas don't have this: they can only be converted to a delegate type, and are defined by the user, not by some other library. Thus, we think it's worth a warning for lambda default parameter value mismatches; it's technically well-defined and the compiler understands what it means, but it's very likely the user is doing something wrong. We could consider a warning wave for method groups mismatches as well, but that will have to depend on whether we thing the signal-noise ratio would be high enough.
Conclusion
Feature is accepted. We will generate custom delegate types for these lambdas, and accept the breaking change to do the same for method groups. We will warn when lambda parameter default values differ from a delegate type they are converted to, if the lambda is not being converted to its natural type.
Null-conditional assignment
https://github.com/dotnet/csharplang/issues/6045
We're looking at old, well-upvoted request: allowing a null-conditional on the left side of an assignment. We generally think it's a good
feature, even if a?.b ??= c
has a very different meaning from a?.b ?? c
.
Conclusion
Proposal accepted, moved into the working set.