开发者社区> 问答> 正文

为什么C#在两种int数组语法上的行为有所不同

C#中的数组在引用类型上隐式为协变的:

object[] listString = new string[] { "string1", "string2" }; 但不是值类型,因此如果更改string为int,则会得到编译错误:

object[] listInt = new int[] {0, 1}; // compile error 现在,您需要担心的是,当您int像以下两种语法那样声明数组时,它们下面没有显式声明类型int,仅区别于new[],编译器将以不同的方式处理:

object[] list1 = { 0, 1 }; //compile successfully object[] list2 = new[] {0, 1}; //compile error 您将object[] list1 = { 0, 1 };成功编译,但是object[] list2= new[] {0, 1};编译错误。

看来C#编译器对待

object[] list1 = { 0, 1 }; 如

object[] list1 = new object[]{ 0, 1 }; 但

object[] list2 = new[] { 0, 1 }; 如

object[] list2 = new int[]{ 0, 1 }; //error because of co-variant 在这种情况下,为什么C#编译器的行为方式不同? 问题来源于stack overflow

展开
收起
保持可爱mmm 2020-02-08 22:07:58 460 0
1 条回答
写回答
取消 提交回答
  • 编译的版本使用数组初始化程序进行初始化list1。C#语言规范§1.110(“数组初始化器”)规定:

    数组初始化程序由一系列变量初始化程序组成,这些变量初始化程序由“ {”和“}”标记包围,并由“,”标记分隔。每个变量初始化器都是一个表达式,对于多维数组,则是一个嵌套数组初始化器。

    使用数组初始化程序的上下文确定要初始化的数组的类型。在数组创建表达式中,数组类型紧接在初始化器之前,或者从数组初始化器中的表达式推断出来。在字段或变量声明中,数组类型是要声明的字段或变量的类型。

    在字段或变量声明中使用数组初始化程序时,例如:

    int[] a = {0, 2, 4, 6, 8}; 它只是等效数组创建表达式的简写形式:

    int[] a = new int[] {0, 2, 4, 6, 8}; 因此很明显,应该编译。

    第二个版本使用显式的数组创建表达式,您可以在其中明确指示编译器创建哪种类型的数组。§1.51.10.4(“数组创建表达式”)规定:

    第三种形式的数组创建表达式称为 隐式类型的数组创建表达式。它与第二种形式相似,不同之处在于未明确给出数组的元素类型,而是将其确定为数组初始值设定项中表达式集的最佳通用类型(第1.50.2.14节)。

    因此,第二个版本相当于

    object[] list2 = new int[] { 0, 1 }; 因此,问题实际上变成了“为什么我不能分配int[]一个object[]”,就像您在问题末尾提到的那样。答案也很简单,如第1.109节(“数组协方差”)所示:

    数组协方差尤其不扩展到值类型数组。例如,不存在允许将an int[] 视为的转换object[]。

    2020-02-08 22:08:11
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载