tags:

views:

63

answers:

2

Is it possible in C# 4.0 method default values parameters as array (for ex. string[] sArray)? if yes, how to implement it?

I tried call function like below:

MethodA(string[] legends=new string[]{"a","b"},float[] values=new float[]{1,2}, string alt="sd");

It's not work

+3  A: 

Default values must be compile-time constant, which means arrays cannot be used.

The standard (pg 312) says this:

The expression in a default-argument must be one of the following:

  • a constant-expression
  • an expression of the form new S() where S is a value type
  • an expression of the form default(S) where S is a value type
Dean Harding
Oh wow that's terrible. It's the same issue as attributes except I'm pretty sure you can actually use arrays for them. Why can't you declare an initialised array? They are constant
Graphain
@Graphain: In what way is any array other than an empty one constant? Non-empty arrays are always mutable. The compiler would have to create a copy of the array on each call, in case something (e.g. the called method) had changed the contents.
Jon Skeet
@Jon Skeet - Well one would assume that if defaults require a constant the compiler would be smart enough to treat an array as read only. The only way that is changing is if someone tinkers with reflection right, which would be the same issue for true constants (e.g. string etc.).
Graphain
@Graphain: There's no such thing as a read-only array. Would the method not be able to pass it to anything else which took an array argument either? You're basically talking about a different type here.
Jon Skeet
@Jon Skeet, my mistake. Still it's not like it would let you use a read-only IEnumerable type is it?
Graphain
@Graphain: Do you mean having a default value which was a sequence? No, you can't specify that as the default value either. Given the workarounds, I can't say I'm *hugely* bothered by this restriction.
Jon Skeet
@Jon Skeet - no, but the workarounds are *almost* the same as before default values existed, except the caller need not specify null. It just seems such an arbitrary coding decision is all but obviously not one worth arguing over since neither of us (presumably in your case :P) can influence the C# architects.
Graphain
@Graphain: It's not arbitrary at all. The mechanism for default values has been in place for ages - it's only that C# exposes it now. Don't underestimate the value of the caller not having to specify the value. Try saving a Word document before and after... I prefer specifying 2 values instead of 18. A "from scratch" design could well have been different, but there are very old constraints here.
Jon Skeet
@Jon Skeet - I always forget how bad some legacy and COM APIs are and forgot that they weren't making IL changes, just C# changes. Thanks as always for the enlightenment.
Graphain
+3  A: 

As others have said, default values can't be arrays. However, one way of avoiding this is to make the default value null and then initialize the array if necessary:

public void Foo(int[] x = null)
{
    x = x ?? new int[] { 5, 10 };
}

Or if you're not going to mutate the array or expose it to the caller:

private static readonly int[] FooDefault = new int[] { 5, 10 };
public void Foo(int[] x = null)
{
    x = x ?? FooDefault;
}

Note that this assumes null isn't a value that you'd want to use for any other reason. It's not a globally applicable idea, but it works well in some cases where you can't express the default value as a compile-time constant. You can use the same thing for things like Encoding.UTF8 as a default encoding.

If you want a value type parameter, you can just make that a nullable one. For example, suppose you wanted to default a parameter to the number of processors (which clearly isn't a compile-time constant) you could do:

public void RunInParallel(int? cores = null)
{
    int realCores = cores ?? Environment.ProcessorCount;
}
Jon Skeet