Why C# allows that only the last parameter of a method is of “variable length”

喜夏-厌秋 提交于 2019-12-12 08:49:18

问题


From what I know, C# allows that only the last parameter of a method is of "variable length", for example:

T f(A a, params B[] b) allows that if you have A r; .... B x, y, z; .... you can call f like f (r, x, y, z). Why C# doesn't also define something like:

T f(params A[] a, params B[] b)

回答1:


Because how would the compiler know when the variable arguments for the first parameter stop?

Pleas tell me what argOne and argTwo should contain inside of the method body:

void Foo( params object[] argOne, params object[] argTwo )
{
    // whatever
} 

Foo( 1, false, "Hello", new object(), 2.3 );



回答2:


Because it would be too complicated to determine when such a construction is actually allowed.
(When the call would be unambiguous)
Although it would be possible to create a good set of rules, they would be rather complicated and difficult to understand. People would end up asking why case X doesn't work, if it has a subtle ambiguity.

For example:

  • Neither type can be an interface or generic parameter
  • If one type is an enum or a numeric type, the other must be a class other than object or Enum
  • If one type is a delegate, the other must not also be a delegate type (nor object, Delegate, nor MulticastDelegate)
  • One type cannot inherit the other
  • All of these rules apply to any types implicitly convertible to the parameter types
  • Both types must be sealed or must be value types

(some of these rules could be enforced at the callsite instead)

In practice, such a feature would have so many restrictions as to be almost worthless.

Therefore, this feature would start with -10,000 points.

It would also create a whole new category of breaking changes. Unsealing a type, adding implicit conversions, or other seemingly trivial things could now break client code.




回答3:


Because of ambiguity. If you went and did:

T f(params int[] a, params int[] b)

And you called:

f(1, 2, 3, 4)

How would the compiler know where one started and the other began? You could argue that such cases could still be flagged as compilation errors and still allow the unambiguous cases to continue, but with inheritance it could get complicated and it just isn't worth it. Pass two arrays instead. I can't think of any situation that would merit two parameter arrays, and even then, it's syntactic sugar. There's no difference between it and just using arrays instead.

(Another example:

T f(params string[] a, params object[] b);

string inherits from object. This is still ambiguous...)




回答4:


There are many edge cases that make this an improbable feature. Consider this example:

public static class Coolifier
{
  public static void BeCool<A,B>(params A[] a, params B[] b)
  {
  }
}

Coolifier.BeCool<string,string> ("I", "don't", "work.", "DO", "I", "?");

The example shows how there is no way to know where the first params [] ends and the next begins.




回答5:


It would pose question and lead to conflicts.

For example, let's say B inherits from A.

How would compiler understand:

f(A1, A2, B1, B2)

Would it mean f({A1, A2}, {B1, B2}) or f({A1, A2, B1}, {B2})?

I think theoretically compiler could be smart and detect conflicts.
However, originally when .NET and C# itself were designed the idea was to try to avoid unambiguous and tricky cases like this.




回答6:


void DoSomething( params object[] p1, params int[] p2 )
{
...   
} 

 DoSomething( 1, 2, 3 );

Think if the compiler could resolve that. Can you code the '...' part? If yes, would it be readable?

I can tell you: It would be a mess.




回答7:


If the 'last parameter' is of variable length, your second/third/n parameter woundn't be necessary 'cause would be contained into the first one according to your sample and would be ambigous:

T f(params A[] a, params B[] b)

b would be contained within a



来源:https://stackoverflow.com/questions/6351878/why-c-sharp-allows-that-only-the-last-parameter-of-a-method-is-of-variable-leng

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!