协方差行为中的数组对象[]

本文关键字:对象 数组 方差行 | 更新日期: 2023-09-27 17:51:03

我有一个编译错误,而将int[]分配给object[](这个问题不是我的)。

可接受的答案表明,这是因为数组协方差(为了更好地理解,请阅读问题和答案)。

现在我的情况是,虽然我不能将int[]分配给object[],因为int是值类型(struct),我想知道为什么我现在可以这样做:

var arrayOfObjects = new object[] { 58, 58, 78 };// it accepts values types as initializers!

如果我初始化数组对象的值类型,为什么这个工作?不应该是相互的不接受值类型?

协方差行为中的数组对象[]

因为您(隐式地)将一个项目接一个项目强制转换为object。您没有将int[]数组分配给object[]变量-您正在从单个int值(得到隐式强制转换和装箱)创建object[]变量。

在没有数组初始化式的情况下:

object[] objarr = new object[1];
objarr[0] = 42; // Fine, translates basically into objarr[0] = (object)42;
int[] intarr = new int[1];
intarr[0] = 42; // Also fine
objarr = intarr; // No can do!

这里您不是在构建int[],整数被装箱成对象,而您正在构建object[]。你也可以给其他东西加框:

var arrayOfObjects = new object[] { true, "false", 1, 10, new StringBuilder() }

从编译器的角度来完成这个观点,给出下面的语句:

void Main()
{
    object[] or = new object[] { 1, 2 };
}

这是编译器发出的IL:

IL_0001:  ldc.i4.2    
IL_0002:  newarr      System.Object
IL_0007:  stloc.1     // System.Object[]
IL_0008:  ldloc.1     // System.Object[]
IL_0009:  ldc.i4.0    
IL_000A:  ldc.i4.1    
IL_000B:  box         System.Int32
IL_0010:  stelem.ref  
IL_0011:  ldloc.1     // System.Object[]
IL_0012:  ldc.i4.1    
IL_0013:  ldc.i4.2    
IL_0014:  box         System.Int32
IL_0019:  stelem.ref  
IL_001A:  ldloc.1     // System.Object[]
IL_001B:  stloc.0     // or
IL_001C:  ret      

编译器获取这些值,对值类型(int)执行box操作,然后调用stelem.ref,将一维数组中提供的索引处的元素的值替换为压入堆栈的ref (type O)值。