Passing an Empty Array as Default Value of an Optional Parameter

Passing an empty array as default value of an optional parameter

You can't create compile-time constants of object references.

The only valid compile-time constant you can use is null, so change your code to this:

public void DoSomething(int index, ushort[] array = null,
bool thirdParam = true)

And inside your method do this:

array = array ?? new ushort[0];

(from comments) From C# 8 onwards you can also use the shorter syntax:

array ??= new ushort[0];

Method parameter array default value

Is there a correct way to do this, if this is even possible at all?

This is not possible (directly) as the default value must be one of the following (from Optional Arguments):

  • 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.

Creating an array doesn't fit any of the possible default values for optional arguments.

The best option here is to make an overload:

public void SomeMethod()
{
SomeMethod(new[] {"value 1", "value 2", "value 3"});
}

public void SomeMethod(String[] arrayString)
{
foreach(someString in arrayString)
{
Debug.WriteLine(someString);
}
}

C# Optional Array Parameter for Class

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;
}
}

Is it possible to have an array parameter with a default value?

Default parameters have to be constant expressions, as stated in the documentation. And constant expressions cannot represent non-empty arrays.

Dart: how to create an empty list as a default parameter

Like this

class Example {
List<String> myFirstList;
List<String> mySecondList;

Example({
List<String> myFirstList,
List<String> mySecondList,
}) : myFirstList = myFirstList ?? [],
mySecondList = mySecondList ?? [];
}

Default Parameter must be a compile-time constant / int[] C#

From MSDN

"the default value must be one of the following :

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."

Arrays you created don't follow any of the above rulles

try this

public void C_Loader(int[] Index1=null, int[] Index2=null , int[] Index3=null)
{
if(Index1 ==null) Index1= new int[] {4,4,4};
if (Index2 == null) Index2 = new int[] { 8, 8, 8 };
if (Index3 == null) Index3 = new int[] { 10, 10, 10 };

.... your code
}

optional array Parameter in C#

The documentation for optional arguments says:

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.

Since new string[0] is neither a constant expression nor a new statement followed by a value type, it cannot be used as a default argument value.

The first code excerpt in your question is indeed a good workaround:

void MyMethod(string[] tags = null)
{
tags = tags ?? new string[0];
// Now do something with 'tags'...
}

Declaring an optional array argument

The other difference is that if you don't pass an argument , it will default to array() or null, which are two very distinct values. You can check for that of course, but you will need to take it into account. empty will work for both, but a foreach loop over null won't work that well, and various array functions will also fail.

What you noticed is correct: Passing null for a typehinted argument only works if you add = null to the declaration. This is not only true for arrays but for objects as well. In PHP there is no way in PHP to make a typehinted argument that is mandatory but can be null. As soon as you add =null to the declaration, you can pass null but you can also omit the parameter.

If to you there is no logical difference between an empty array or null, I would choose the first method of defaulting to an empty array. Then at least you'll know that the input is always an array. I think that add clarity to both the implementer of the function and the programmer(s) who use it. But I guess that's just an opinion and not even a strong one.

My main advice would be to not make the argument optional at all. In my experience this will make the usage of such functions unclear, especially as the code grows and more arguments are added.

Default value data annotation for empty array

The problem with arrays is that it has a fixed length. You can resize the array using Array.Resize() but that too needs a fixed length.

A better way is to use List instead of an array:

public class CreateCustomerOrderByIdDto
{
[FromRoute]
public uint Id { get; set; }

[FromBody]
public List<OrderPosition> OrderPositions { get; set; }
}

By default, the list object OrderPositions will have null value; which is a good way to represent no items present in the list.

If you still need the list to be empty by default, instead of null, you can set the default value as below:

public List<OrderPosition> OrderPositions { get; set; } = new List<OrderPosition>();


Related Topics



Leave a reply



Submit