int []使用“错误”的Console.WriteLine重载

时间:2016-01-13 19:35:29

标签: c# arrays

我正在和一位同事一起学习一些基本的C#教程,我们遇到了一个有趣的难题。

以下代码按预期工作:

string[] strings = { "1", "2", "3" };
Console.WriteLine("{0}, {1}, {2}", strings);

它获取字符串数组,并使用Console.WriteLine(string format, params object[] arg)方法的WriteLine重载将字符串“1,2,3”打印到控制台。

但是以下代码不起作用:

int[] ints = { 1, 2, 3 };
Console.WriteLine("{0}, {1}, {2}", ints);

您收到FormatException消息Index (zero based) must be greater than or equal to zero and less than the size of the argument list.使用Intellisense我可以看到它正在尝试使用Console.WriteLine(string format, object arg0)重载,这就是我们收到该消息的原因,它没有'请将ints视为数组,尽管它显然是。

如果我们切换到更明显的:

int[] ints = { 1, 2, 3 };
Console.WriteLine("{0},{1},{2}", ints[0], ints[1], ints[2]);

它再次起作用并再次使用params object[]重载。

是否有理由不将int[]视为该方法的数组? Int32是一个结构的事实是否会产生影响?如果是这样,为什么?

修改

我用相同格式的双打进行了快速测试,但那些效果不好,这让我觉得这个类型是一个结构,但我仍然不明白为什么会产生影响

2 个答案:

答案 0 :(得分:8)

这适用于string个对象的原因是C#的Array Covariance功能。

  

对于任何两种引用类型AB,如果从AB存在隐式或显式引用转换,则同样的引用转换也存在于数组类型A[]

的数组类型B[]

存在从stringobject的隐式转换,因此WriteLine会使用string[]数组代替object[]数组。

int[]没有协方差,因为int 不是引用类型。如果您想使用显式转换,可以这样做:

object[] ints = (new int[]{ 1,2,3 }).Cast<object>().ToArray();
Console.WriteLine("{0}, {1}, {2}", ints);       

Demo.

答案 1 :(得分:5)

是的,这是因为int是值类型。它试图找到最佳匹配。 string[]可转换为object[],但int[]不是因为结构数组不是协变的。作为解决方法,您可以使用

int[] ints = { 1, 2, 3 };
Console.WriteLine("{0}, {1}, {2}", ints.Cast<Object>().ToArray());