C# params keyword with two parameters of the same

2019-01-18 13:51发布

问题:

I just encountered something with C# today that I hadn't thought of before. I have two methods in my class, one an overload of the other. They are declared like so:

  1. public void RequirePermissions(params string[] permissions)...
    
  2. public void RequirePermissions(string message, params string[] permissions)...
    

In my code, I tried to call the first one like so:

RequirePermissions("Permission1", "Permission2");

...expecting it to call the first overload. Well it called the second overload. The only way I can get it to call the first method in this case is to manually pass a string[] object like so:

RequirePermissions(new string[] { "Permission1", "Permission2" });

Now, this behavior doesn't confuse me because I understand that the compiler can't tell which method I actually wanted to call based on my provided parameters. But was I not careful this could have gone unnoticed in my code. It seems as though Microsoft should have made the compiler throw an error when it encountered a situation like above. Does anyone have any thoughts on this? Is there another way to call the first overload other than the "solution" I posted?

回答1:

Agreeing with Adam, I'd change it to something like:

public void RequirePermissions(params string[] permissions)

public void RequirePermissionsWithMessage(string message, params string[] permissions)


回答2:

Personally, I'd do it this way:

  1. public void RequirePermissions(params string[] permissions)...
    
  2. public void RequireMessageAndPermissions(string message, 
        params string[] permissions)...
    

People fall too in love with overloading sometimes, and when you combine that with a love for the params keyword, you just increase the confusion level for whomever eventually has to take over your code.



回答3:

It looks like there is no other way.

You can find explanation to this behaviour in C# spec http://www.jaggersoft.com/csharp_standard /17.5.1.4.htm and here http://www.jaggersoft.com/csharp_standard/14.4.2.1.htm (paragraph 2)

a parameter array is precisely equivalent to a value parameter (§17.5.1.1) of the same type.

and

The expanded form of a method is available only if the normal form of the method is not applicable and only if a method with the same signature as the expanded form is not already declared in the same type



回答4:

Yes, I agree it should probably be a warning when using variable length argument arrays causes an ambiguous overload - it's very much an edge case, and people almost certainly don't mean to create such situations.

I also don't know of any way, other than that you posted, to avoid the call resolution that occurs - other than to avoid doing it in the first place, which I would highly recommend!



回答5:

You could not use params and be explicit with your signatures.

public void RequirePermissions(string[] permissions)...
public void RequirePermissions(string message, string[] permissions)..