locked
Using methods with both a params parameter and optional parameters

    Question

  • Ok here is some code:

            static void Main(string[] args)
            {
                Console.WriteLine("Average: {0}", CalculateAverage(THIS_HAS_TO_BE_SOMETHING?!?!, 10, 10, 10));
                Console.ReadLine();
            }
            static double CalculateAverage(string caller = "programmer", params double[] values)
            {
                Console.WriteLine("{0} has called the CalculateAverageMethod", caller);
                Console.WriteLine("Array contains {0} different doubles.", values.Length);
                double sum = 0;
                if (values.Length == 0)
                {
                    return sum;
                }
                for (int i = 0; i < values.Length; i++)
                {
                    sum += values[i];
                }
                return (sum / values.Length);
            }

    I think impossible to not declare anything for the optional parameter in the CalculateAverage method as the params needs to be supplied some data WHICH comes after the optional parameter? Optional parameters are made for a reason, how are we as programmers supposed to use it in this case i.e make the
    THIS_HAS_TO_BE_SOMETHING?!?!
    text in the code be nothing so we can actually optionally supply a argument there or not.

    Personal Website: http://www.xanather.com



    • Edited by Xanather Thursday, July 05, 2012 11:49 AM
    • Moved by CoolDadTxMVP, Moderator Thursday, July 05, 2012 5:01 PM Language related (From:Visual C# General)
    Thursday, July 05, 2012 11:48 AM

Answers

  • In C#, you can omit the last arguments.

    The following method:

    static double CalculateAverage(string caller = "programmer", double value = 0)
    can be called like this:
    CalculateAverage("some string", 42);
    CalculateAverage("some string");
    CalculateAverage();

    If the argument you want to provide comes after an argument you want to omit, you must name it:
    CalculateAverage(value: 42);

    The same is true with a params array. And since you have only one name for the argument, you have to provide it as an array:
    CalculateAverage(values: new double[] { 10, 10, 10 });

    • Proposed as answer by Marcel RomaMVP Thursday, July 05, 2012 4:40 PM
    • Marked as answer by Xanather Friday, July 06, 2012 9:33 AM
    Thursday, July 05, 2012 4:16 PM
  • Hi,

    In C# you have positional arguments and named arguments. Optional parameters, like the one you used, always come *after* required ones, and the only exception to this is a parameter array, which by definition must be the last in the method's signature. So, if you need to call CalculateAverage(), you'll have to specify the params array as a named argument, as Louis told you. This way you can decouple the params array argument from its position in the call. But be aware that the optional parameter will still be melt into the caller not into the callee. So don't use this kind of things too liberally if your callee happens to be in a class library. Otherwise, you'll end up with difficult versioning issues.

    Marcel


    P.S. Please understand Louis's remark about omitting the last arguments in the context of your question. You can't really omit the last argument in C# if it's not a params array. This would not compile.
    Thursday, July 05, 2012 4:39 PM

All replies

  • You could overload the CalculateAverage method, like so:

            static void Calc(string caller, params double[] values)
            {
                Console.WriteLine(values.Sum().ToString());
            }
    
            static void Calc(params double[] values)
            {
                Calc("programmer", values);
            }
    
            static void Main(string[] args)
            {
                Calc("Mr. Magoo", 10, 20, 30);
    
                Calc(100, 200, 300);
            }
    

    Thursday, July 05, 2012 12:54 PM
  • In C#, you can omit the last arguments.

    The following method:

    static double CalculateAverage(string caller = "programmer", double value = 0)
    can be called like this:
    CalculateAverage("some string", 42);
    CalculateAverage("some string");
    CalculateAverage();

    If the argument you want to provide comes after an argument you want to omit, you must name it:
    CalculateAverage(value: 42);

    The same is true with a params array. And since you have only one name for the argument, you have to provide it as an array:
    CalculateAverage(values: new double[] { 10, 10, 10 });

    • Proposed as answer by Marcel RomaMVP Thursday, July 05, 2012 4:40 PM
    • Marked as answer by Xanather Friday, July 06, 2012 9:33 AM
    Thursday, July 05, 2012 4:16 PM
  • Hi,

    In C# you have positional arguments and named arguments. Optional parameters, like the one you used, always come *after* required ones, and the only exception to this is a parameter array, which by definition must be the last in the method's signature. So, if you need to call CalculateAverage(), you'll have to specify the params array as a named argument, as Louis told you. This way you can decouple the params array argument from its position in the call. But be aware that the optional parameter will still be melt into the caller not into the callee. So don't use this kind of things too liberally if your callee happens to be in a class library. Otherwise, you'll end up with difficult versioning issues.

    Marcel


    P.S. Please understand Louis's remark about omitting the last arguments in the context of your question. You can't really omit the last argument in C# if it's not a params array. This would not compile.
    Thursday, July 05, 2012 4:39 PM
  • Thanks everyone :)

    Personal Website: http://www.xanather.com

    Friday, July 06, 2012 2:19 PM