6

C#4.0 brings optional parameters, which I've been waiting for for quite some time. However it seems that because only System types can be const, I cannot use any class/struct which I have created as an optional parameter.

Is there a some way which allows me to use a more complex type as an optional parameter. Or is this one of the realities that one must just live with?

2
  • There is no restriction as to "System types". What leads you to believe that? Commented Apr 21, 2010 at 1:10
  • they can be other types, but the only default value available is null (or possibly something which the type can implicitly convert from but I can't test this as I don't have 4.0 at work)) Commented Apr 21, 2010 at 1:41

2 Answers 2

9

The best I could come up with for reference types was:

using System; public class Gizmo { public int Foo { set; get; } public double Bar { set; get; } public Gizmo(int f, double b) { Foo = f; Bar = b; } } class Demo { static void ShowGizmo(Gizmo g = null) { Gizmo gg = g ?? new Gizmo(12, 34.56); Console.WriteLine("Gizmo: Foo = {0}; Bar = {1}", gg.Foo, gg.Bar); } public static void Main() { ShowGizmo(); ShowGizmo(new Gizmo(7, 8.90)); } } 

You can use the same idea for structs by making the parameter nullable:

public struct Whatsit { public int Foo { set; get; } public double Bar { set; get; } public Whatsit(int f, double b) : this() { Foo = f; Bar = b; } } static void ShowWhatsit(Whatsit? s = null) { Whatsit ss = s ?? new Whatsit(1, 2.3); Console.WriteLine("Whatsit: Foo = {0}; Bar = {1}", ss.Foo, ss.Bar); } 
Sign up to request clarification or add additional context in comments.

3 Comments

I was thinking along those lines but as I was using a struct it didn't like that either. Don't know why I didn't just make the func take a nullable version (Size? size = null) though.
System.Nullable... Now I remember where I got the idea for an extra "initialized" field in the struct. :)
FYI, you can still use the ?? operator with a nullable struct.
5

You can use any type as an optional parameter:

using System; class Bar { } class Program { static void Main() { foo(); } static void foo(Bar bar = null) { } } 

Okay, I reread your question and I think I see what you mean - you want to be able to do something like this:

static void foo(Bar bar = new Bar()) { } 

Unfortunately this is a not allowed since the value of the default parameter must be known at compile time so that the compiler can bake it into the assembly.

1 Comment

"bake it into the assembly" -- People overlook the fact that changing the default value of a parameter in a library won't change it in client code that hasn't been recompiled.