Counter-intuitive syntax of C# variable arguments

I’ve come across a corner case in C# syntax when variable arguments do not work as you’d intuitively expect:

    class Problem
    {
        static void foo(params object[] ps)
        {
            System.Console.WriteLine("got {0} parameters", ps.Length);
        }

        public static void Main()
        {
            foo(null, null, null, null);
            foo(null, null, null);
            foo(null, null);
            foo(null); // <-------------- CRASH?!
            foo();
        }
    }

When type of the only argument matches the type of arguments array, the parser treats it as an attempt to pass precomposed arguments array.

What they should do is to always treat one argument as one argument (logically), and require params modifier whenever the programmer wants to pass a precomposed array of arguments:

foo(null); // would pass one parameter: ps.Length == 1
foo(params null); // would pass the array: ps == null

That would fit very nice given ref and out already work this way.

Python uses exactly this approach (it does a lot of things right way, that’s why I love it):

foo(args) # always treats args as one variable argument
foo(*args) # always treats args as array of variable arguments
comments powered by Disqus