协方差行为中的 Array object[]
Array object[] in covariance behavior
I had a compile error while assinging int[]
to 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(O 类型)值压入堆栈。
I had a compile error while assinging int[]
to 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(O 类型)值压入堆栈。