-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[Suggestion] Remove/relax CS1738 "Named argument specifications must appear after all fixed arguments have been specified" #518
Comments
Yes! Another frequent wish. |
@gafter I would be interested in your feedback regarding the best way to move this proposal forward. The current language specification contains the following limitation:
I would suggest the following alternative:
This change in wording should not negatively impact the ability of named arguments to be used for overload resolution, even in cases like the following: private static void Foo(int x, int a) { }
private static void Foo<T>(T y, int a) { }
private static void Bar()
{
Foo(3, 4);
Foo(y: 3, 4);
} I am worried about the complexity this feature would introduce in dealing with the following: private static void Foo(int x, int y) { }
private static void Foo<T>(T y, int x) { }
private static void Bar()
{
Foo(3, 4);
Foo(y: 3, x: 4); // Invokes Foo(int, int)
Foo(y: 3, 4); // Invokes Foo<T>(T, int)
} |
@sharwell The next step would be to find someone on the LDM @dotnet/csharplangdesign who believes this is both desirable and of higher priority than many other things we could do, and who is willing to invest their time to push the issue forward. That LDM member would then volunteer to "champion" this proposal, and bring it to LDM to be triaged. I believe there are two or three members of the LDM on your team. |
@sharwell Also, one should compare doing this language feature with the alternative of doing an IDE feature that fills in the parameter names for you at the call site. |
DoSomething(isEmployed:true, name, age); The use of bool parameters like this is a code smell in my view, as it's very likely that void DoSomething(bool isEmployed, string Name, int Age)
{
if (isEmployed)
{
// do something with employed person
}
else
{
// do something with unemployed person
}
} In such situations, it makes more sense to provide two methods: DoSomethingWhenEmployed(name, age);
DoSomethingWhenUnemployed(name, age); (Updated to retract the claim that most use cases will be for |
But then you double each overload that includes the bool. And more bools causes them to increase exponentially. The main reason bools are used is laziness. A new enum requires typing more characters and LOC than the ADTs would be even better, preventing the use of invalid values. |
@DavidArno passing Literals of various kinds are also frequent in unit tests and named parameters can help readers be confident that the correct methods are being tested. |
Like most things which could break BC in the language, that should probably be left to an analyzer. But this proposal is a good start and can even be coupled with an IDE feature that targets literal arguments. |
I have this problem with ints too, not just bools and null. |
Yes, any time you are passing a literal value where it is not clear what the value represents it is useful to use a named parameter to help document what is happening in the code, but a nuisance that all following parameter must now be named as well. |
@gafter I believe the main value in this comes from the fact that the place I see this requested the most is in code reviews, where IDE features aren't playing a role. Perhaps we can get GitHub someday to incorporate Roslyn into their PR UI (can you imagine?!), but until then I have to say this is a pretty compelling request! |
I woudl love this feature. And I would champion this. My hope is that it could slot in close to being a 'bugfix' sized change. |
Talked to Cyrus. I'll go ahead and start a championed proposal. Link coming shortly. |
Opened #570 to start the process. I'll write a proposal that can be discussed in LDM to get a rough sense of prioritization. |
@sharwell There are tools like Reviewable that build on top of GitHub's PRs. If you want to use Roslyn with PRs, I think an external tool like that is more likely than GitHub adding explicit support for C#. |
Would this allow using named arguments with In https://github.com/dotnet/corefx/issues/19599#issuecomment-300527721, this method was proposed: public class Task
{
public static Task When(TaskStatus all, TaskStatus any, params Task[] tasks);
} It would be great if such method could be called as: Task.When(all: TaskStatus.RanToCompletion, any: TaskStatus.Faulted, task1, task2) I think this would be useful for other |
@sharwell The problem you point out is not new. Calling private static void Foo(int x, int y) { }
private static void Foo<T>(T y, int x) { } |
@svick Thanks for bringing up the For each candidate method considered for applicability:
In your example with |
I also like to use named arguments whenever I call a method with multiple parameters of the same type; it makes it harder to accidentally get the order of parameters wrong, by "making wrong code look wrong". Currently this makes me also use named arguments for every other parameter as well, even when some of them have different types and so should be covered by the type checker. |
(a bit late, but) private static void Foo(int x, int y) { }
private static void Foo<T>(T y, int x) { }
private static void Bar()
{
Foo(3, 4);
Foo(y: 3, 4); // warning
} Determining the problemCollect candidates with an argument called
so as it usually happens: passing 2x MessageMethod Possible solutions
Correction: removal of unnecessary overload
Correction: private static void Foo(int x, int y) { }
private static void Foo<T>(int x, T y) { } or private static void Foo(int y, int x) { }
private static void Foo<T>(T y, int x) { } After change, a specialized overload
Correction: change of argument name, e.g.: private static void Foo(int z, int x) { }
private static void Foo<T>(T y, int x) { }
Correction:
(not solution, but rather conscious use) ¹ - name of the first named argument that caused this problem. I think that the unconscious changes in the way of choosing overload is a serious problem. |
@gafter Can we close this as now implemented? |
Yes; this was implemented in C# 7.2 per #570 |
@dsaf commented on Thu Jun 02 2016
I like using named arguments for code readability when passing literals. However the subj limitation forces me to either not use them or specify them for every subsequent argument:
@bondsbw commented on Mon Jun 06 2016
I like this, but only if argument order aligns with the parameter list until at least the last unnamed argument.
Example:
@dsaf commented on Tue Jun 07 2016
@bondsbw of course.
The text was updated successfully, but these errors were encountered: