3

I tried the following code:

class Program: ProgParent
    {

        public int Max(params int[] op)
        {
            return 0;
        }

        public int Max(int i, params int[] op)
        {
            return 1;
        }

        public int Max(int i, int j, params int[] op)
        {
            return 2;
        }

        public static void Main(string[] args)
        {
            System.Console.WriteLine((new Program()).Max(5, 6, 7, 8));
            System.Console.ReadKey();
        }
    }

It executes, and uses the most specific function available. But the compiler gives no warning or error about this. Why?

3
  • Your code doesn't compile - the first two method signatures are identical. After removing one of them it's fine though. Why wouldn't it be? Commented Mar 31, 2009 at 7:05
  • Yes, that was the original version, I just wanted to add a new method here Commented Mar 31, 2009 at 7:16
  • your code does just fine, after I remove the base class (class Program instead of class Program: ProgParent). I don't know where your problem? Commented Mar 31, 2009 at 13:04

2 Answers 2

4

The C# language spec says:

When performing overload resolution, a method with a parameter array may be applicable either in its normal form [i.e. passing an array] or its expanded form [i.e. passing a variable number of parameters]. The expanded form of a method is available only if the normal form of the method is not available and only if a method with the same signature as the expanded form is not already declared in the same type"

In a (slightly simplified) nutshell: If overload resolution is ambiguous, the compiler chooses the non-params overload.

I guess the reasons for that decision (instead of making code like yours illegal) include:

  • If your method has the signature: void fn(params object[] p), you want to have some way to call the "normal form" (by passing an object[]). So the compiler has to handle ambiguous cases anyway.
  • Creating a temporary array is a lot more expensive than a method call, so you might want to create non-params overloads with 1,2,3 parameters that behave the same but are more efficient. (like e.g. String.Format)
Sign up to request clarification or add additional context in comments.

Comments

2

Ignoring the build errors (which I'm putting down to typos) - what warning would you expect or want? It is finding a matching overload and using it...

Strictly speaking, I can call different overloads - by passing arrays, but yes, the usage isn't entirely clear.

Without the multiple overloads with params, this pattern is used quite heavily in things like string.Concat etc (which underpins + for strings under the bonnet).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.