C# - 编译器错误 - 将int []赋给object []

Ang*_*wal 7 c# compiler-errors

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            object[] obj = new object[3];
            obj[0] = new object();
            obj[1] = "some string";
            obj[2] = 10;

            string[] strings = new string[] { "one", "two", "three" };
            obj = strings; //---> No Error here, Why ?

            int[] ints = new int[] { 1, 2, 3 };
            obj = ints; /*-> Compiler error - Cannot implicitly convert type 'int[]' to 'object[]', Why ?*/ 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在执行上述步骤时遇到编译器错误.但是,在上一步中,没有错误.有人能解释一下这种行为吗?我正在使用VS 2010.

编辑 - 为了完整性,再次,这将无法编译 - .NET 4.0中的差异支持现在已经清理.我们可以使用新的关键字与泛型参数.

    List<object> objectList = new List<object>();
    List<string> stringList = new List<string>();
    objectList = stringList;
Run Code Online (Sandbox Code Playgroud)

Gab*_*abe 6

只有引用类型的数组(如String)可以分配给其他引用类型的数组(如Object).由于int是值类型,因此可能无法将其数组分配给其他类型的数组.

更具体地说,这称为阵列协方差.它仅在存储在阵列中的位模式与目标类型兼容时才有效.例如,a String[]中的位都是对字符串的引用,可以安全地复制到存储对象引用的内存位置.但是,值类型数组存储元素的实际数据(而不是仅仅引用它们).这意味着int[]将实际的32位整数存储在数组的元素中.由于无法将32位整数安全地复制到存储对象或任何其他类型的引用的内存位置,因此无法将它们的数组分配给任何其他类型的数组.

请注意,从技术上讲,a的位int可以安全地复制到存储a的存储单元中uint(反之亦然).这意味着你应该能够做类似的事情int[] x = new uint[10].这实际上不是协方差,C#不允许它.但是,它在CLR中是合法的,如果你愿意,你可以说服C#让你这样做.