0

The method String.Format has the following overload:

public static string Format (string format, params object?[] args);

which I supposed was meant for formatting many args of the same type into a string with a format for each of the args, similarly to str.format(*args) in python 3.

However, when I call:

var a = String.Format("{0} {1:0.00000000e+000} {2:0.00000000e+000}", new Double[] {1,2,3} );

I get the error:

Index (zero based) must be greater than or equal to zero and less than the size of the argument list.

When I would expect the output in a to be

"1 2.00000000e+000 3.00000000e+000"

similarly to a="{0:d} {1:1.8e} {2:1.8e}".format(*[1,2,3]) in python 3.

Calling

var a = String.Format("{0}", new Double[] {1,2,3} );

fixes the error but returns in a the wrong result:

"System.Double[]"

What is the correct c# way to get the python result I expected (with different formatting for the first column)?

-

PS: This related question gives me an insight, but I'm sure there's an easier way that I'm missing:

String.Concat((new Double[] { 1,2,3 }).Select(k => string.Format("{0}", k)))

this can't be the best (or correct) way. Specially because it makes the overload String.Format(String, params object[]) useless, IMHO.

1
  • I know an ugly probably not the best way, which cannot achieve different formatting: String.Concat((new Double[] { 1,2,3 }).Select(k => string.Format("{0}", k)))
    – Girardi
    Commented Mar 16, 2024 at 16:43

2 Answers 2

1

Creating an object array instead of a double array fixes the problem:

string a = String.Format("{0} {1:0.00000000e+000} {2:0.00000000e+000}", 
                      new object[] { 1, 2, 3 });

The problem is that since you are not passing an object[] but a double[], C# assumes that this double array is a single parameter of the params array which is of type object[], i.e. it passes the method an object array containing a single item being a double array.

new object[] { new double[] { 1, 2, 3 } }

If the double values are given as an array variable, you could write:

double[] d = [1, 2, 3]; // C# 12 collection expression
string a = String.Format("{0} {1:0.00000000e+000} {2:0.00000000e+000}",
                         d.Cast<object>().ToArray());

Since the parameter is a params array, we can also simply write

string a = String.Format("{0} {1:0.00000000e+000} {2:0.00000000e+000}", 1, 2, 3);

Or we can use string interpolation where the numbers do not represent indexes but are the ones we want to format

string a = $"{1} {2:0.00000000e+000} {3:0.00000000e+000}";
1

Using string.Join() will work to do this for joining items of an array.

double[] d = new double[] { 1.0, 2.0, 3.0 };
string s = string.Join(" ", d);

This joins the values into a string and any delimiter can be added in the first parameter of string.Join().

To get the desired output of the formatted string, a Cast<object>() is needed. This will cast it to an array of objects which string.Format accepts, which is why simply passing in a double[] to string.Format fails and throws the exception.

object[] args = d.Cast<object>().ToArray();
string x = string.Format("{0} {1:0.00000000e+000} {2:0.00000000e+000}", args);

I hope this answers your question. Other than this, a loop might work for formatting the string if an unknown amount of objects need to be formatted.

1
  • This partially solves the problem, although it doesn't take care of the different formatting for each column... If I would need to use String.Join, what is the point of having the overload String.Format(String, params object[])?
    – Girardi
    Commented Mar 16, 2024 at 16:51

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.