为什么我可以将1传递为short而不传递int变量i?


146

为什么第一个和第二个Write起作用而最后一个不起作用?有没有一种方法可以让我全部允许3个人,并检测它是否为1,(int)1或我传入?真的为什么允许一个,但最后一个呢?第二个被允许,但最后一个没有被我震惊。

演示以显示编译错误

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!?
    }
}

2
我也为此感到迷惑,尽管它们应该是可转换的,但我经常不得不将int转换为短函数调用……
Mathieu Dumoulin 2012年

2
@MathieuDumoulin它们是可铸造的,这就是为什么您可以铸造它们。但这是一个有损失的转换(有很多int简而言之),所以隐式强制转换是不可能的,这就是为什么要写(short) i
亚伯2012年

Answers:


186

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

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

此规则与隐式转换应该无损的准则相一致。

6.1.8隐式常量表达式转换

隐式常量表达式转换允许进行以下转换:

  • 常数表达式型的(§7.18)int可以转换为类型sbytebyteshortushortuint,或ulong,所述的提供的值常数表达式是在目标类型的范围内。
  • 常数表达式类型的long可转化为类型ulong,提供的值常量表达式不为负。

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


67

由于存在截断的可能,因此没有从int到的隐式转换short。但是,编译器可以将常量表达式视为目标类型。

1?没问题:这显然是有效值shorti?没那么多– short.MaxValue例如,它可能是一些值> ,并且在一般情况下编译器无法检查。


所以...我有多明确都没有关系...> _ <。您是否知道我是否可以检测到是否传递了litereal或int变量?

@ acidzombie24您不能。但是为什么要这么做呢?
亚当·霍兹沃思

@ acidzombie24我认为您无法检测到。但是,您可以使用模板参数,然后使用反射来获取其类型。
康拉德·鲁道夫

3
@ acidzombie24在运行时无法传递文字。因此,您只需要在编译时检查一下即可。
贾斯汀

1
@ acidzombie24在这种情况下,是否可以选择将参数接受为Expression<Func<int>>?然后,您可以传递() => 1() => i在函数内部,您可以检查传递的实体是否包含捕获的变量或常量值。
康拉德·鲁道夫

8

int 字面可以隐式转换到short。鉴于:

您不能将存储量较大的非文字数字类型隐式转换为short

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


3
您的回答有点错误。您不应该使用文字,而是使用常量表达式。特别是第二个例子不是文字
CodesInChaos 2012年

6

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

编辑:有人击败了我!


3

因为在非文字类型到大号short 之间不会有任何隐式转换。

隐式转换仅可用于常量表达式。

public static void Write(short v) { }

当您将integer值作为参数传递时short

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

3

编译器告诉您代码为何失败:

cannot convert `int' expression to type `short'

所以这是您应该问的问题:为什么转换失败?我用Google搜索“ c#convert int short”,最后在MS C#页面上找到了short关键字:

http://msdn.microsoft.com/zh-CN/library/ybs77ex4(v=vs.71).aspx

如该页面所述,short仅允许将文字从较大的数据类型隐式转换为。编译器可以告知文字何时超出范围,但不会其他情况,因此需要确保在程序逻辑中避免了超出范围的错误。这种保证是由演员提供的。

Write((short)i)

0

从int-> short转换可能会导致数据截断。这就是为什么。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.