Proposal: allow asterisk (*) in method calls to use the default #7640
-
Hi, This proposal is about making it easier to pass values for optional arguments in method calls. To clarify, if you have a method with multiple optional arguments, and you only need to specify a value for some of them, you need to resort to named arguments instead of positional arguments. Take this example: void GitCommit(string message, bool amend = false, bool allowEmpty = false, bool dryRun = false)
{
} Today, you need to use named arguments a lot to work with these kinds of methods. GitCommit("required", dryRun: true);
GitCommit("required", allowEmpty: true);
GitCommit("required", true, dryRun: true); Often I would prefer to use positional arguments but there is nothing in the language today that makes it possible. With this proposal I would like to introduce the asterisk (*) operator to make it possible to call such methods using positional arguments: GitCommit("required", *, *, true);
GitCommit("required", *, true);
GitCommit("required", true, *, true); The asterisk would indicate that the default value for the argument should be used, which could be anything (hence the asterisk.) So it would be lowered into code which you would otherwise have to write yourself: // lowered code
GitCommit("required", false, false, true);
GitCommit("required", false, true);
GitCommit("required", true, false, true); This example is of course trivial for demonstration purpose. In the real world, these methods can get really hairy, especially when optional strings with a default value are involved. Please also consider this: we often already have a named variable that we pass on to the method call. For example this could be a GUI for Git where we bind checkboxes to variables. var message = MessageControl.Text;
var amend = AmendControl.Checked;
var dryRun = DryRunControl.Checked;
GitCommit(message, amend, dryRun: dryRun); Could instead be rewritten as: var message = MessageControl.Text;
var amend = AmendControl.Checked;
var dryRun = DryRunControl.Checked;
GitCommit(message, amend, *, dryRun); I also expect some people might use this to make it unambiguously clear that default values are at play: GitCommit(message, *, *, *); Or even more explicitly: GitCommit(message, amend: *, allowEmpty: *, dryRun: *); Although enabling that style of programming is not a primary goal of my request. Thank you for your time and consideration. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 14 replies
-
GitCommit("required", default, default, true);
GitCommit("required", default, true);
GitCommit("required", true, default, true); |
Beta Was this translation helpful? Give feedback.
-
The art of good code is readability. Easy to read code is easier to understand and so is less prone to mistakes, and is quicker and easier to modify and support. With that in mind, I am utterly opposed to this as For me, Python's "keyword-only parameters" approach is far more desirable, where we'd specify the method like this: void GitCommit(string message, *, bool amend = false, bool allowEmpty = false, bool dryRun = false) ... with the In lieu of that, the best practice in C# is to define a flags enum, [Flags]
enum GitOptions
{
None = 0b000,
Amend = 0b001,
AllowEmpty = 0b010,
DryRun = 0b100
}
void GitCommit(string message, GitOptions options = GitOptions.None) ... Your examples become far more readable then: GitCommit("required");
GitCommit("required", GitOptions.DryRun);
GitCommit("required", GitOptions.AllowEmpty);
GitCommit("required", GitOptions.Amend|GitOptions.DryRun); |
Beta Was this translation helpful? Give feedback.
Fundamentally, what the ecosystem does is "idiomatic". And the ecosystem tends to follow the design guidelines to not rock the boat and to make .net feel like a consistent and complimentary set of tools and libraries. We're unlikely to change the language for the niche case. Unless we truly believed it was better and there was enough value in dragging everyone to that new place.
That's a tall order, and nothing so far in this space has given us the motivation to go that route.