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

Eva*_*sch 9 c# arrays

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

以下代码按预期工作:

string[] strings = { "1", "2", "3" };
Console.WriteLine("{0}, {1}, {2}", strings);
Run Code Online (Sandbox Code Playgroud)

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

但是,以下代码不起作用:

int[] ints = { 1, 2, 3 };
Console.WriteLine("{0}, {1}, {2}", ints);
Run Code Online (Sandbox Code Playgroud)

你得到一个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]);
Run Code Online (Sandbox Code Playgroud)

它再次工作并再次使用params object[]过载.

有没有理由它没有看到该int[]方法的数组?Int32作为结构的事实是否有所作为?如果是这样,为什么?

编辑

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

das*_*ght 8

这与string对象一起使用的原因是C#的数组协方差特性.

对于任何两个引用类型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);       
Run Code Online (Sandbox Code Playgroud)

演示.


Kyl*_*e W 5

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

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