Advertisement

Tip Jar:

One-Time Donation

Recurring Monthly $2 Donation Appreciated

The tip jar is to help contribute to keeping this site going. If you like what you see... feel free to help out!

Text Link Ads

Optional parameters in C# and X++

Go directly to Source

In the upcoming 4.0 version of C# the language now supports optional parameters – just like X++. The following is a valid method declaration in both languages:


public void foo(int parameter1, int parameter2 = 0, int parameter3 = 100)
{
}

There are a few differences between the languages with regards to optional parameters:


Named parameters


In X++ you can only omit optional parameters starting from the last parameter. C# makes it possible to omit any optional parameter. For example:


foo(5, parameter3: 1000)

will call foo(5, 0, 1000).


prmIsDefault


C# doesn’t provide a way to determine, if a parameter was omitted by the caller, or the caller passed in a value identical to the default value. In X++ the prmIsDefault() method can be used to determine this. However, the use cases for this method are rare – and often fragile. For example, consider this X++ class:


class BaseClass
{
    int value;
    public void init(int _value = 0)
    {
        if (prmIsDefault(value))
        {
            value = /* some complex calculation */
        }
        else
        {
            value = _value;
        }
    }
}
Now someone comes along and extends the class:
class MyClass extends BaseClass
{
    str myStr;
    public void init(int _value = 0)
    {
        myStr = ‘foo’;
        super(_value);
    }
}
Can you see the problem? This following code will never call the complex calculation (which probably was the intention):
MyClass myClass = new MyClass();
To solve the problem MyClass needs to be implemented as:
class MyClass extends BaseClass
{
    str myStr;
    public void init(int _value = 0)
    {
        myStr = ‘foo’;
        if (prmIsDefault(_value))
            super();
        else
            super(_value);
    }
}

Which really is terrible, as the implementation of the derived class depends on the implementation of the base class. This is bound to break eventually. Add a few more optional parameters and a few more levels of depth in the class hierarchy, and you’ll have a real nightmare. My recommendation is to only use prmIsDefault() in private methods – as they can’t be overridden. In C# you can easy live without this method, as you can achieve the same in a more robust manner using method overloading:


class BaseClass
{
    int value;
    public void init()
    {
        int _value = /* some complex calculation */
        this.init(_value);
    }
    public void init(int _value)
    {
        value = _value;
    }
}
<humor>It is a good thing we solved the dangling semicolon issue – otherwise it would haunt the C# community in a not too distant future.</humor>
Make sure to visit the author of this post!

No Comments

Comments are closed.

MCP Logos