31

Is there any way to create a constant object(ie it cannot be edited and is created at compile time)?

I am just playing with the C# language and noticed the optional parameter feature and thought it might be neat to be able to use a default object as an optional parameter. Consider the following:

//this class has default settings
private const SettingsClass DefaultSettings = new SettingsClass ();

public void doSomething(SettingsClass settings = DefaultSettings)
{

}

This obviously does not compile, but is an example of what I would like to do. Would it be possible to create a constant object like this and use it as the default for an optional parameter??

user623879
  • 4,066
  • 9
  • 38
  • 53
  • 1
    Just an aside: Avoid using language features just because you can. Use them because they are the right tool for the job. Default parameters are not the right tool for what you want to do. Cheers! – Jon Mar 21 '11 at 00:41
  • 1
    If this were Python, this would be a perfectly acceptable use of default parameters. I see no reason that default parameters aren't the right tool for the job (aside from the fact that it's not valid in C#). – Gabe Mar 21 '11 at 01:00

3 Answers3

48

No, default values for optional parameters are required to be compile-time constants.

In your case, a workaround would be:

public void doSomething(SettingsClass settings = null)
{
    settings = settings ?? DefaultSettings;
    ...
}
Ani
  • 111,048
  • 26
  • 262
  • 307
7

Generally what you want is not possible. You can fake it with an "invalid" default value as Ani's answer shows, but this breaks down if there is no value you can consider invalid. This won't be a problem with value types where you can change the parameter to a nullable type, but then you will incur boxing and may also "dilute" the interface of the function just to accommodate an implementation detail.

You can achieve the desired functionality if you replace the optional parameter with the pre-C# 4 paradigm of multiple overloads:

public void doSomething()
{
    var settings = // get your settings here any way you like
    this.doSomething(settings);
}

public void doSomething(SettingsClass settings)
{
    // implementation
}

This works even if the parameter is a value type.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • Agreed, but I was looking for optional parameter method. – user623879 Mar 21 '11 at 00:30
  • @user623879: I added a new first paragraph, which makes the answer more complete. – Jon Mar 21 '11 at 00:34
  • @User: It really doesn't matter; the parameter is optional in this case as well. IMHO Jons method is undeniably superior to Anis. – Noon Silk Mar 21 '11 at 00:38
  • You are probably right that this is the better way to do it from a SW design standpoint, and this was how I was going to do it originally, but my question was about optional parameters etc, so I accepted Anis answer. – user623879 Mar 21 '11 at 00:59
  • 1
    @user623879: I care more about what solution you will actually use than whose answer you accepted :) – Jon Mar 21 '11 at 01:00
  • @NoonSilk but it doesn't work for, say, a service interface. – MasterOfTwo Feb 13 '20 at 11:50
-5

You could use the readonly attribute, instead of const. For example:

//this class has default settings 
private readonly SettingsClass DefaultSettings = new SettingsClass (); 

public void doSomething(SettingsClass settings = DefaultSettings) 
{ 
} 
Michael
  • 23
  • 1