为什么我可以传递1作为一个短的,而不是整型变量 i?

为什么第一次和第二次写作有效,而最后一次没有效?有没有一种方法,我可以允许所有3个并检测它是1,(int)1还是 i 传入?为什么只允许一个,而不是最后一个呢?第二次是允许的,但不是最后一次真的让我感到震惊。

演示显示编译错误

using System;
class Program
{
public static void Write(short v) { }
static void Main(string[] args)
{
Write(1);//ok
Write((int)1);//ok
int i=1;
Write(i);//error!?
}
}
6777 次浏览

由于存在截断的可能性,因此不存在从 intshort的隐式转换。但是,可以将 常数表达式视为目标类型 被编译器

1?没问题: 它显然是一个有效的 short值。i?没有这么多-它可以是一些值 > short.MaxValue,例如,编译器不能在一般情况下检查。

我相信这是因为在前两个中传入的是文字/常量,但是在第三个中传入的是整数时没有自动的类型转换。

编辑: 有人抢在我前面了!

前两个是常量表达式,最后一个不是。

C # 规范允许常量从 int 到 short 的隐式转换,但不允许其他表达式这样做。这是一个合理的规则,因为对于常量,编译器可以确保值适合目标类型,但对于普通表达式则不能。

此规则符合隐式转换应该是无损的指导原则。

6.1.8隐式常量表达式转换

隐式常量表达式转换允许下列转换:

  • int类型的 常数表达式常数表达式(7.18)可以转换为 sbytebyteshortushortuintulong类型,只要 常数表达式常数表达式的值在目标类型的范围内。
  • long类型的 常数表达式常数表达式可以转换为 ulong类型,只要 常数表达式常数表达式的值不是负的。

(引自 C # 语言规范3.0版)

一个 int 字面意思可以隐式转换为 short。然而:

不能隐式地将存储大小较大的非文字数值类型转换为 太短了

因此,前两个工作,因为文字的隐式转换是允许的。

因为不会有任何 含蓄转换之间的 不是字面意思类型较大的尺寸短。

隐式转换只能用于常数表达式。

public static void Write(short v) { }

integer值作为参数传递给 short的位置

int i=1;
Write(i);  //Which is Nonliteral here

编译器会告诉你代码失败的原因:

cannot convert `int' expression to type `short'

因此,你应该问这样一个问题: 为什么这种转换会失败?我在谷歌上搜索了“ c # turn int short”,最后在 MS C # 页面上找到了 short关键字:

Http://msdn.microsoft.com/en-us/library/ybs77ex4(v=vs.71).aspx

正如本页所述,从较大的数据类型到 short的隐式转换只允许文字转换。编译器可以判断文字何时超出范围,但不能判断其他情况,因此需要确保您在程序逻辑中避免了超出范围的错误。这种安慰是由演员们提供的。

Write((short)i)

从 int-> short 转换可能导致数据截断。

从 short-> int 的转换是隐式发生的,但是 int-> short 会抛出编译错误,因为它可能导致数据截断。