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 and final 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;
    }
}
It is a good thing we solved the dangling semicolon issue – otherwise it would haunt the C# community in a not too distant future.