为什么我不能将值类型的数组分配给对象数组变量?
Why cant I assign array of value type into object array variable?
赋值到a
没问题,赋值到b
导致编译错误,为什么?
Dim a As Object() = { 1 }
Dim b As Object() = ({ 1 })
错误信息是:
BC30333 Value of type 'Integer()' cannot be converted to 'Object()' because 'Integer' is not a reference type.
第一个示例有效,因为它推断并创建了一个 Object
数组。
然而在第二个例子中,括号内的部分首先被评估并被推断为一个 Integer
数组,然后它试图将其分配给 b
(这当然不起作用,因为你不能像那样转换整个数组)。
根据 MSDN 文章 Local Type Inference Option Infer
将使编译器根据您赋予变量的值来决定类型:
The compiler infers the type of the variable from the type of the initialization expression.
我想我已经弄明白了:
因为必须正确完成所有操作,所以必须首先评估括号,然后 语句的其余部分。编译器在对整个语句求值之前不知道您稍后是否尝试对括号内的数组做更多的事情。因此,它假定您需要一个整数数组。
在第一个示例中没有括号,因此可以直接计算整个语句这预计会产生一个对象数组。当编译器发现它需要执行隐式转换时,它会选择 Object()
,因为这就是你所说的你想要的,因为这是它唯一可以评估的东西。
从字面上回答标题中的问题——因为值类型数组实际上只包含一个连续的内存块来保存每个值类型,但是 objects 由一个连续的内存块组成,其中包含 object 个引用 .
当然,您可以通过 装箱 将值类型转换为 object 引用。但是不能保证 object 引用和值类型占用相同数量的内存,即使有,单个连续内存块也不能同时容纳值类型 和 一个 object 同时引用。
如果您确实需要执行这样的 "assignment",则必须以某种方式分配一个新数组(例如,可能通过 LINQ Cast
和 ToArray
方法)并且,一旦创建,这两个数组便完全独立 - 对一个数组中值的更改不会反映在对另一个数组中装箱值的更改中。
赋值到a
没问题,赋值到b
导致编译错误,为什么?
Dim a As Object() = { 1 }
Dim b As Object() = ({ 1 })
错误信息是:
BC30333 Value of type 'Integer()' cannot be converted to 'Object()' because 'Integer' is not a reference type.
第一个示例有效,因为它推断并创建了一个 Object
数组。
然而在第二个例子中,括号内的部分首先被评估并被推断为一个 Integer
数组,然后它试图将其分配给 b
(这当然不起作用,因为你不能像那样转换整个数组)。
根据 MSDN 文章 Local Type Inference Option Infer
将使编译器根据您赋予变量的值来决定类型:
The compiler infers the type of the variable from the type of the initialization expression.
我想我已经弄明白了:
因为必须正确完成所有操作,所以必须首先评估括号,然后 语句的其余部分。编译器在对整个语句求值之前不知道您稍后是否尝试对括号内的数组做更多的事情。因此,它假定您需要一个整数数组。
在第一个示例中没有括号,因此可以直接计算整个语句这预计会产生一个对象数组。当编译器发现它需要执行隐式转换时,它会选择 Object()
,因为这就是你所说的你想要的,因为这是它唯一可以评估的东西。
从字面上回答标题中的问题——因为值类型数组实际上只包含一个连续的内存块来保存每个值类型,但是 objects 由一个连续的内存块组成,其中包含 object 个引用 .
当然,您可以通过 装箱 将值类型转换为 object 引用。但是不能保证 object 引用和值类型占用相同数量的内存,即使有,单个连续内存块也不能同时容纳值类型 和 一个 object 同时引用。
如果您确实需要执行这样的 "assignment",则必须以某种方式分配一个新数组(例如,可能通过 LINQ Cast
和 ToArray
方法)并且,一旦创建,这两个数组便完全独立 - 对一个数组中值的更改不会反映在对另一个数组中装箱值的更改中。