使用数组作为string.Format()的参数

31
尝试将数组用作 string.Format() 方法的参数时,会遇到以下错误:

FormatException: 索引(从零开始)必须大于或等于零,并且小于参数列表的大小。

代码如下:

place = new int[] { 1, 2, 3, 4};
infoText.text = string.Format("Player1: {0} \n Player2: {1} \n Player3: {2} \n Player4: {3}", place);

数组包含四个值,而String.Format()中的参数也是相同的。

导致这个错误的原因是什么?

(infoText.text只是一个普通的字符串对象)


3
你正在传递一个int[]而不是一个string[] - Alfie Goodacre
也许可以这样写:string.Format("玩家1: {0} \n 玩家2: {1} \n 玩家3: {2} \n 玩家4: {3}", place[0], place[1], place[2], place[3]);。它的工作原理是将一个对象传递给字符串中的每个 {}。 - Awais
3
仅供参考,您可以更动态地创建字符串,而不是使用string.format并硬编码玩家数量,例如:infoText.text = string.Join("\n", place.Select((p,i) => $"Player{i+1}: {p}")); - Me.Name
@Me.Name 看起来非常不错。我会尝试一下。谢谢! - martin36
4个回答

27

您可以使用 System.LinqSelect() 扩展方法将 int 数组转换为字符串数组并传递它。

infoText.text = string.Format("Player1: {0} \nPlayer2: {1} \nPlayer3: {2} \nPlayer4: {3}", 
                              place.Select(x => x.ToString()).ToArray());

编辑:

在C# 6及以上版本中,您还可以使用字符串插值而不是使用string.Format()函数。

infoText.text = $"Player1: {place[0]}\nPlayer2: {place[1]} \nPlayer3: {place[2]} \nPlayer4: {place[3]}";

请查看此代码片段以供参考。


1
所以参数可以是 string[] 数组,但不能是 int[] 数组? - martin36
@martin36 不仅限于 string[] - 你的数组应该是对象或字符串类型。 - Balagurunathan Marimuthu

10
快速修复。
var place = new object[] { 1, 2, 3, 4 };

C#不支持从int[]object[]的协变数组转换,因此整个数组被视为object,因此这个带有单个参数的重载被调用。


1
C#是支持协变数组转换的(例如从string []object []),但在这种情况下,转换还涉及值类型的装箱,这就是为什么它不起作用的原因。 - Joey
4
他写道:"不支持将int[]转换为object[]的协变数组转换"。;-) - Tim Schmelter

6

可以为params参数传递一个显式数组,但它必须具有相匹配的类型。string.Format有一些重载,其中以下两个对我们很有用:

string.Format(string, params object[])
string.Format(string, object)

在您的情况下,将 int[] 视为 object 是唯一可行的转换方法,因为 int[] 不能隐式(或显式)转换为 object[],所以 string.Format 看到了四个占位符,但只有一个参数。您需要声明正确类型的数组。

var place = new object[] {1,2,3,4};

“params object[]”和普通的“object[]”数组有什么区别? - martin36
@martin36:您可以将params参数视为任意数量的参数。编译器会自动将它们包装在一个数组中以调用该方法。 - Joey

3

正如其他人已经说过的那样,你不能将 int[] 转换为 object[]。但是你可以使用 Enumerable.Cast<T>() 来解决这个问题:

infoText.text = string.Format
(
      "Player1: {0} \n Player2: {1} \n Player3: {2} \n Player4: {3}",                        
      place.Cast<object>().ToArray()
);

顺便提一下,如果你使用的是C# 6或更高版本,你可以考虑使用插值字符串代替string.Format

infoText.text = $"Player1: {place[0]}\n Player 2: {place[1]} \n Player 3: {place[2]} \n Player 4: {place[3]}";

我正在使用Unity,它只有C# 2版本。 - martin36
哦,抱歉,但无论如何感谢您的回答。我会记住它以备将来使用。 - martin36
@martin36 没问题,这可能对其他读者也是一个有用的建议 :) - Matías Fidemraizer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接