Sur*_*rat 0 c# language-design implicit-conversion
我正在学习C#并遇到一些让我对它的语法感到不舒服的事情.
情况1
byte num1 = 10; // works
int ten = 10;
byte num2 = ten; // Compile error: Cannot implicitly convert 'int' to byte. An explicit conversion exists.
Run Code Online (Sandbox Code Playgroud)
在第一个语句中,编译器隐式地将文字10(类型为int)强制转换为byte,相反,它在第三个语句中不执行相同操作.
案例2
int[] numbers1 = { 10, 20, 30 }; // works
int[] numbers2;
numbers2 = { 10, 20, 30 }; // Compiler error: Invalid expression term: {
Run Code Online (Sandbox Code Playgroud)
上面缩短的数组初始化程序在每个语句中都不起作用.
而且可能还有更多这样的不一致......
似乎错误版本是正确的,因为它们是按照定义的语法,非错误版本(对于类似的情况)是语言创建的构造,只是使语言易于编码.
但是在我们使用它的每个地方仍然不一致吗?
Mat*_*son 10
案例1是C#语言规范明确涵盖的特殊情况.
从§6.1.9隐式常量表达式转换:
隐式常量表达式转换允许以下转换:
•如果constant-expression的值在目标类型的范围内,则int类型的常量表达式(第7.19节)可以转换为sbyte,byte,short,ushort,uint或ulong类型.
•如果constant-expression的值不是负数,则long类型的常量表达式可以转换为ulong类型.
因为变量ten未声明为,const所以上述规则不适用,并且不允许隐式转换,并且您收到编译错误.
请注意,如果你改变ten是const int ten = 10;那么它会工作,因为,当然,它现在是一个常数.
案例2由new运营商的特征启用.
来自§1.8数组:
new运算符允许使用数组初始值设定器指定数组元素的初始值,数组初始值设定项是在分隔符{和}之间写入的表达式列表.
以下示例使用三个元素分配和初始化int [].
int [] a = new int [] {1,2,3};
请注意,数组的长度是根据{和}之间的表达式数推断的.可以进一步缩短局部变量和字段声明,以便不必重新调整数组类型.
int [] a = {1,2,3};
观察它如何允许您省略new关键字,即使它实际上是new在幕后使用操作符.
因此,这个语法糖由new运算符提供,它只能在隐式使用时使用new.
在您的示例中,当您单独声明和初始化时,您仍然可以部分使用此语法,但您必须明确使用new关键字:
int[] numbers2;
numbers2 = new [] { 10, 20, 30 };
Run Code Online (Sandbox Code Playgroud)
现在你可以争辩说编译器可以允许语法没有new,因为它知道类型numbers2并且可以推断a的存在{并且}意味着它必须是数组初始化.但是,这需要一个新的规则,我想,语言设计者并不认为它会被用来证明添加它是合理的.