Reputation: 10305
I know this can be done using null
so I have a workaround for that, but I was wondering if there was a better way that I can have an optional int[]
parameter for a class?
class PriceLevels
{
public int[] priceLevels { get; }
private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };
public PriceLevels(int[] newPriceLevels = defaultPriceLevels)
{
priceLevels = newPriceLevels;
}
}
This gives me an error saying it is an invalid expression defaultPriceLevels
must be constant. How can I fix this?
One workaround that I can thing of is this, but I don't really like the solution
class PriceLevels
{
public int[] priceLevels { get; }
private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };
public PriceLevels(int[] newPriceLevels = null)
{
if(newPriceLevels == null)
priceLevels = defaultPriceLevels;
else
priceLevels = newPriceLevels;
}
}
Upvotes: 15
Views: 4967
Reputation: 37299
A better design all together would be to have 2 constructors (constructor overload) one that gets a int[]
and another that doesn't:
class PriceLevels
{
public int[] priceLevels { get; set; }
private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };
public PriceLevels()
{
priceLevels = defaultPriceLevels;
}
public PriceLevels(int[] newPriceLevels)
{
priceLevels = newPriceLevels;
}
}
If not, don't know if i'd call this "better" but you can use the params
keyword:
class PriceLevels
{
public int[] priceLevels { get; set; }
private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };
public PriceLevels(params int[] newPriceLevels)
{
priceLevels = newPriceLevels.Length == 0 ? defaultPriceLevels : newPriceLevels;
}
}
Also, depending on design, I'm not convinced that it is PriceLevels
responsibility to decide what the default values are and maybe it should get it as a dependency in any case - See SOLID and Dependency Injection. Then you'd have only 1 constructor:
class PriceLevels
{
public int[] priceLevels { get; set; }
public PriceLevels(int[] newPriceLevels)
{
priceLevels = newPriceLevels;
}
}
Upvotes: 17
Reputation: 11478
Another option in the Crowd :), which is closest to your original code
class PriceLevels
{
public int[] priceLevels { get; set; }
private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };
public PriceLevels(int[] newPriceLevels = null)
{
priceLevels = newPriceLevels ?? defaultPriceLevels;
}
}
Upvotes: 7
Reputation: 271885
Just create an overload of the constructor! It can be really easily done with one line of code!
public PriceLevels() : this(defaultPriceLevels) { }
Then, remove the default parameter value from the original constructor:
public PriceLevels(int[] newPriceLevels)
Actually, you also need to declare defaultPriceLevels
as static
. Hopefully you don't mind that.
Upvotes: 4
Reputation: 5141
You can overload your constructor.
class PriceLevels
{
public int[] priceLevels { get; private set; }
private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };
public PriceLevels()
{
priceLevels = defaultPriceLevels;
}
public PriceLevels(int[] newPriceLevels)
{
priceLevels = newPriceLevels;
}
}
Upvotes: 9
Reputation: 15415
Optional array parameters are not possible in C#. From MSDN
Each optional parameter has a default value as part of its definition. If no argument is sent for that parameter, the default value is used. A default value must be one of the following types of expressions:
- a constant expression;
- an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;
- an expression of the form default(ValType), where ValType is a value type.
Therefore a "workaround" has to be used. Either check for null (as you suggested) or you can use a default constructor.
Upvotes: 3
Reputation: 4717
You could create another constructor with no parameters that would just pass your defaultPriceLevels variable to the constructor you already have? You'd have to change the variable to static too.
e.g.
class PriceLevels
{
public int[] priceLevels { get; }
private static int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };
public PriceLevels(int[] newPriceLevels = null)
{
if (newPriceLevels == null) priceLevels = defaultPriceLevels;
else priceLevels = newPriceLevels;
}
public PriceLevels() : this(defaultPriceLevels)
{ }
}
Upvotes: 7