Click here to Skip to main content
Click here to Skip to main content

A Workaround Method To Achieve Default Parameters In C#

By , 10 Oct 2006
Rate this:
Please Sign up or sign in to vote.

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

About the Author

Sean Yixiang Lu
Software Developer
Singapore Singapore
This guy loves computer programming, software design and development. He is interested and specialized in C family languages, especially C#, Java, Objective-C and D Programming Language. Ruby and Python are starting to interest him as well.

Comments and Discussions

 
GeneralNice but... PinmemberRalph Varjabedian20-Nov-07 23:44 
GeneralWhile that's all well and good... PinmemberCraig G. Wilson11-Oct-06 2:34 
GeneralRe: While that's all well and good... PinmemberYixiang Lu11-Oct-06 4:21 
GeneralResolve line lengths PinmemberColin Angus Mackay10-Oct-06 23:14 
GeneralRe: Resolve line lengths PinmemberYixiang Lu10-Oct-06 23:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 11 Oct 2006
Article Copyright 2006 by Sean Yixiang Lu
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid