views:

52

answers:

2

I am starting to take advantage of optional parameters in .Net 4.0

The problem I am having is when I try to declare an optional parameter of System.Drawing.Color:

public myObject(int foo, string bar, Color rgb = Color.Transparent)
{
    // ....
}

I want Color.Transparent to be the default value for the rgb param. The problem is, I keep getting this compile error:

Default parameter value for 'rgb' must be a compile-time constant

It really kills my plan if I can only use primitive types for optional params.

+1  A: 

I'm not a huge fan of optional parameters for cases like this at all. IMO the best use case for optional parameters is interop with COM, where optional parameters are used quite a bit. Situations like these are one of the reasons why (I would guess) that optional parameters didn't make it into the language until 4.0.

Instead of creating an optional parameter, overload the function like so:

public myObject(int foo, string bar) : this (foo, bar, Color.Transparent) {};

public myObject(int foo, string bar, Color RGB) {
...
}
Dave Markle
that's actually what I had before, but in my case, because there are so many overloads of the constructor, it just makes more sense to have a handful of optional params and keep one constructor.
Neil N
I would argue that it doesn't, and a good counterexample is the problem you're running into right now. There are quite a number of functions all around the standard .NET libraries that have *quite* a number of overloads. Take Convert.ToInt32() for example...Defining multiple overloads also gives you the ability to document their usage separately. Oftentimes certain combinations of optional parameters make sense while others do not. Optional parameters don't give you the ability to convey this using only the function signature itself, while an overload (to some extent) does.
Dave Markle
Aside from the Color param, which I might just replace with an int, optional parameters have allowed me to remove about 100 lines of redundant code. There is much less to maintain now.
Neil N
@Neil, don't worry, optional parameters are great mainly for the reason you pointed out. They are an excellent way of reducing redundant crap from your source code. And every line of code you don't have is one less line that can't cause bug and doesn't need maintained.
Matthew Whited
+5  A: 

Nullable value types can be used to help in situations like this.

public class MyObject 
{
    public Color Rgb { get; private set; }

    public MyObject(int foo, string bar, Color? rgb = null) 
    { 
        this.Rgb = rgb ?? Color.Transparent;
        // .... 
    } 
}

BTW, the reason this is required is because the default value is populated at the call point during compile and static readonly values are not set until runtime. (By the type initializer)

Matthew Whited
I did this without Visual Studio so it may need some minor tweaks.
Matthew Whited
Ths wont work, Color is not nullable.
Neil N
@Neil N, the question mark after the type name `Color` makes that structure a `Nullable<Color>`.
Matthew Whited
Ah, right, the question mark. This now works. Thanks
Neil N