Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Workaround Method To Achieve Default Parameters In C#

0.00/5 (No votes)
10 Oct 2006 1  
An article on a workaround solution to achieve default parameters in C# using the parameter array feature.

Introduction

One of the very few things I missed in C++ when I was learning Java, is the default parameter feature. I had been hoping C# would bring back this feature. Unfortunately, I was told there is no default parameter feature in C#, the day I started learning C#. I was like, OK, we can live without default parameters. However, I just couldn't get default parameters out of my head, during the past years of writing C# programs. From time to time, I encountered situations where default parameters would have saved time and probably improved performance as well. So, here I am hacking my way into some brilliant/clumsy solution to it.

Background

The idea is simple if you have heard of the terms "parameter array" or "variable arguments", or the "params" keyword. The "params" keyword of C#, allows you to specify a variable number of parameters for a method. I guess 99% percent of people who write C# code have used the parameter array, because our very good friend Console.WriteLine(...) itself can take variable number of arguments. And if you want to write your own method that takes a parameter array, you use the "params" keyword. It works like this:

void PrintNumbers(params int[] numbers)
{
    Console.WriteLine("Count: {0}", numbers.Length);
    foreach (int n in numbers)
    {
        System.Console.WriteLine(numbers);
    }
}

void Test()
{
    PrintNumbers();
    PrintNumbers(1);
    PrintNumbers(2, 3);
    PrintNumbers(4, 5, 6);
    PrintNumbers(7, 8, 9, 10);
    // Basically you can go on like this forever,

    // and they all call exactly the same method above.

}
Now, a parameter array means any number of parameters (0 or more), and a default parameter means 0 or 1 parameter. Well, it's too obvious that default parameter is just a special case of a parameter array.

Implementation

Now, let us use the "params" keyword and get the default parameter.

class DefaultParameterTest
{
    private const int DEFAULT_ARG = 0;
    
    /// <summary>

    /// Purpose of this method...

    /// </summary>

    /// <param name="fixedArg">meaning of this parameter...</param>

    /// <param name="defaultArg">

    /// meaning of this parameter... 

    /// Note that this parameter is optional, and its default value is 0.

    /// </param>

    void TakeDefaultArgument(int fixedArg, params int[] defaultArg)
    {
        if (defaultArg.Length > 1)
            throw new ArgumentException("Too many arguments");

        int defaultArgValue;
        if (defaultArg.Length == 0)
            defaultArgValue = DEFAULT_ARG;
        else
            defaultArgValue = defaultArg[0];

        // use defaultArgValue for the following part of the method

        // ...

    }

    void Test()
    {
        // The following 3 calls achieve exactly the same result.


        // use default argument

        TakeDefaultArgument(9);
 
        // use user specified argument

        TakeDefaultArgument(9, 0); 

        // a wired way to pass in user defined argument, but legal

        TakeDefaultArgument(9, new int[] { 0 }); 


        // The following calls are invalid


        // compilation error

        TakeDefaultArgument(9, "0"); 

        // no compilation error or warning, but runtime exception

        TakeDefaultArgument(9, 0, 1); 
    }
}

I used int for illustration, but basically the default parameter can be any type.

Points of interest

There are many limitations and drawbacks of this workaround. (Otherwise it wouldn't be called a "workaround" anyway). Here are some of those:

The number of "defaultable" parameters is limited to only one, and it must be at the end of the parameter list.

The default parameter is type safe. But it gets quite tricky when the type of your default parameter itself is an array. (Probably more discussion on this later.)

If too many arguments are passed in, there are no compilation errors, not even warnings. Exception will be thrown at runtime. This is painful, because error checking is moved from compilation time to runtime, which is less efficient and more dangerous.

You can pass in an array of one element and it still works, though the method is expecting 0 or 1 element as an argument. This is because the C# parameter array can take not just single or multiple arguments, but also take a single array of arguments.

You cannot see the default value in the method's signature. The best solution I can think of is putting the default value in your XML style comments in an obvious way.

So a word of caution: if you ever want to use default parameters like this, document your method very carefully to make sure everybody else using this method knows exactly what's going on.

History

  • 11 Oct 2006 - First draft.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here