1

I'm new to C# and have been struggling to find an idiomatic way to initialize a list within a constructor.

Related questions that don't quite solve the issue:

This works, but with a flaw:

class Datapoint { public bool Debug { get; set; } public string Pattern { get; private set; } // I would prefer to initialize this list in the constructor public List<Dictionary<string, dynamic>> operations = new List<Dictionary<string, dynamic>>(); // constructor public Datapoint(bool debug = false, string pattern = "" // I would prefer operations to go here // but the following doesn't work: // List<Dictionary<string, dynamic>> operations = // new List<Dictionary<string, dynamic>>() ) { Debug = debug; Pattern = pattern; } } // Let's define some Datapoints class Definitions { public static Datapoint turtles = new Datapoint ( pattern: @"turtle pattern", // I would prefer operations to go here ) { operations = { new Dictionary<string, dynamic> { ["func"] = "stitch_lines" } } }; } 

The flaw is that I cannot set operations as private, otherwise I get an error when creating turtles.

Ideally I would like operations to be a parameter of the constructor, but I am missing something as every combination I try yields this error:

Default parameter value for operations must be a compile-time constant.

Thanks in advance for any insights.

2
  • You can take in List<Dictionary<string, dynamic>> operations = null and then check for null in the constructor. Commented Nov 10, 2015 at 22:51
  • @zimdanen If you want to post that as a solution I'll accept it, otherwise let me know and I'll write it up in case someone else has the same problem. Commented Nov 10, 2015 at 23:07

3 Answers 3

2

You can take in a null and then check for it in your constructor:

public Datapoint( bool debug = false, string pattern = "", List<Dictionary<string, dynamic>> operations = null ) { Debug = debug; Pattern = pattern; this.operations = operations ?? new List<Dictionary<string, dynamic>>(); } 

However, see the comments of D Stanley's answer for a discussion of drawbacks in the general case.

Sign up to request clarification or add additional context in comments.

3 Comments

Fixed the assignment to this.operations that was broken for the !=null case, +1.
@zx81: Thanks! I should have caught that.
Pleasure, please feel free to change it or format it the way you prefer, just wanted to plug the whole. :)
1

As the error indicates, default values must be compile-time constants. I would do this as two overloads:

// constructor public Datapoint(bool debug = false, string pattern = "") { Debug = debug; Pattern = pattern; operations = new List<Dictionary<string, dynamic>>(); } public Datapoint(List<Dictionary<string, dynamic>> operations, bool debug = false, string pattern = "") { Debug = debug; Pattern = pattern; this.operations = operations; } 

Note that you need to reorder the parameters in the second overload since optional parameters must go at the end of the parameter list.

10 Comments

Thanks for your reply. :) The issue with this (unless I'm missing something) is that I still have to instantiate turtles the same way, so I cannot set operations as private.
Yeah I didn't understand your question at first. See my edits. You can make it private if you have it as a constructor parameter. If you want it to be optional just have two overloads.
Thanks. Your new line List<Dictionary<string, dynamic>>() operations) is one of the constructs I had tried, but VS2015 gives me a lot of squigglies with it.
Check my edits again - I had an extra () and optional parameters must go at the end.
@zimdanen I get it, but the drawback is that there's no way to pass null as a legitimate value. It may not be a problem in this case, but it is a problem when using optional parameters this way (and one reason why I prefer overloads to optional parameters in general).
|
1

Avoid using optional parameters this way

//constructor public Datapoint( bool debug = false, //dangerous string pattern = "",//dangerous List<Dictionary<string, dynamic>> operations = null ) 

Instead use:

//constructor public Datapoint( bool? debug = null, string pattern = null, List<Dictionary<string, dynamic>> operations = null ) { Debug = debug.HasValue && debug.Value; Pattern = pattern; this.operations = (operations == null) ? new List<Dictionary<string, dynamic>>() : operations ; } 

Source: C# In Depth – Optional Parameters and Named Arguments

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.