Consider string.Format()
whose parameters are a string and, among others in the overload list, an object[]
or many objects.
This statement
This is quite an old question, but I recently got the same issue. And I haven't seen an answer that works for me, so I'll share the solution I found.
.ToString()
on the int array, which returns one single parameter containing the type name rather than the parameter list itself. It doesn't do that with a string array, because the target type is already a string - but with any other kind of array the same issue happens (for example bool[]
). var arr1 = new int[]{1,2};
with string.Format("{0}", arr1)
: As long as you have only {0}
in the format string, you get only the type name "System.Int32[]"
back (and no exception occurs). string.Format("{0}{1}", arr1)
, then the exception occurs - because arr1
is misinterpreted as one parameter - and for the compiler, a 2nd one is missing.arr1
, i.e. if you try to do (object[])arr1
- you're getting:
CS0030 Cannot convert type 'int[]' to 'object[]'
Solution:
Filling in each element of the int array is not a solution that works for me, because in my project I am creating a format template string dynamically during runtime containing the {0}...{n}
- hence I need to pass an array to String.Format
.
So I found the following workaround. I created a generic helper function (which of course could be an extension method too if you prefer):
// converts any array to object[] and avoids FormatException
object[] Convert(T[] arr)
{
var obj = new List
Now if you try that in the example below which is showing up the FormatException:
// FormatException: Index (zero based) must be greater than or equal to zero
// and less than the size of the argument list
var arr1 = (new int[] { 1, 2 });
string.Format("{0}{1}{0}{1}", arr1).Dump();
Fix: Use
Convert(arr1)
as 2nd parameter forstring.Format(...)
as shown below:
// Workaround: This shows 1212, as expected
var arr1 = (new int[] { 1, 2 });
string.Format("{0}{1}{0}{1}", Convert(arr1)).Dump();
Try example as DotNetFiddle
Conclusion:
As it seems, the .NET runtime really misinterprets the parameter by applying a .ToString()
to it, if it is not already of type object[]
. The Convert
method gives the runtime no other choice than to do it the right way, because it returns the expected type. I found that an explicit type conversion did not work, hence the helper function was needed.
Note: If you invoke the method many times in a loop and you're concerned about speed, you could also convert everything to a string array which is probably most efficient:
// converts any array to string[] and avoids FormatException
string[] ConvertStr(T[] arr)
{
var strArr = new string[arr.Length];
for (int i = 0; i < arr.Length; i++)
{
strArr[i]=arr[i].ToString();
}
return strArr;
}
This is working as well. To convert from a different datatype, such as a dictionary, you can simply use
string[] Convert(Dictionary coll)
{
return ConvertStr(coll.Values.ToArray());
}
Update: With string interpolation, another short way to solve it is:
var baz = string.Format("{0} and {1}", myInts.Select(s => $"{s}").ToArray());