2012-04-08 87 views
25

超越CastAsC#转换为可空类型?

  • 之间的定期无聊区别,如果我知道苹果水果这样我就可以用(Fruit)apple - 如果它不是,它抛出一个异常
  • as value可以检查是否成功[不会抛出异常...]

不过的Ive阅读@EricLippert article这件事,有关于空值类型一个很好的例子:

short? s = (short?)123; 
int? i = s as int?; 

不会编译...

无法将类型“短? “到'int?'通过参考转换,装箱转换,拆箱转换,包装转换或空类型转换

很好。

那么,为什么这样的:

short? s = (short?)123; 
    int? i = (int?)s; 

是否编译? (!事与愿违知道sint? - 它应该去BANG但它不是...)

的演员在这里检查要远远超过前者例如更致命的(其中又以爆炸)

我不好意思问这个话题很多。

在此先感谢。

+1

您描述了Eric Lippert所写的内容 - 该类型将会编译,而'as'操作符不适用于可空类型的情况。 – Yahia 2012-04-08 18:55:04

+0

@Yahia但我们是否同意short不是INT? – 2012-04-08 18:59:09

+0

短不是int BUT可以被转换/转换为int - 这就是你要告诉编译器:make this short int。 – Yahia 2012-04-08 19:01:11

回答

23

在您的第一个示例中,as运算符试图将对象s用作int?。由于int?不在short?的继承链中的任何位置,因此此操作失败。

在第二个示例中,您实际上是在创建一个新的int? i,其值为short? s。这是一个更慷慨的操作,因为它不必保留左侧的原始对象s

这里重要的一点是,as不允许做任何不保留对象身份的事情。明确的强制转换可以。

下面介绍一下C#标准说有关(int?)形式是如何工作的:

6.1.4隐式可空转换

是在不可为空值操作 类型也可以使用

预定义的隐式转换与这些类型的可为空形式。对于每一个的 预定隐式标识和数值转换该转换 从非空值类型S到非空值类型T,所述 以下隐式可为空的转换存在:

·选自S的隐式转换?到T ?.

·从S到T的隐式转换。

基于从S上的底层 转换至T进行的隐式转换可为空的评价如下:

·如果为空的转换是从S'到T?:

o如果源值为空(HasValue属性为false),则 结果为类型T?的空值。

o否则,转换被评估为从S?展开。到 S,然后是从S到T的潜在转换,然后是从T到T?的换行(第4.1.10)。

·如果可以为空的转换是从S到T?,转换 被评估为从S到T的底层转换,然后是从T到T?的 。

+0

超出这个解释theres仍然这个行'(int?)s'哪些与继承/拳击时代有关....但它工作,那是我不明白的东西。 – 2012-04-08 19:04:07

+0

@RoyiNamir,我不太明白。从'short'到'int'的转换(在C,Java和其他地方都是如此),C#规范描述了如何进行转换并使其可工作在可空类型上。 (我在上面添加了相关摘录。) – sblom 2012-04-08 19:13:15

+1

@sblom我认为你应该在上面的段落中加上'粗体'这样说'重要的一点是,不允许做任何不能保留你的对象身份的事情。一个明确的演员可以。“ - 我认为这是这个核心。至于说是允许的,我同意,这对我来说很清楚(因为并不是真的),正如Eric所说的那样,对于short-s没有任何算术(对此无关紧要,但它更容易理解,至少我是这个转换),它转换为int。 – NSGaga 2012-04-08 19:24:40

3

的例子:

int? i = (int?)s; 

编译器是否因为投的是你,告诉你知道的东西,它不能推断编译器,也就是说,s可以转换为一个int?

如果转换不成功,您只会在运行时得到异常。

+2

在运行时没有例外..... – 2012-04-08 18:56:50

+0

@RoyiNamir - 对不起,应该补充说只有在演员不工作。 – Oded 2012-04-08 18:57:52

0

我认为这是事业as失败的情况下,你会得到一个“有效” null结果,所以假阳性。在第二种情况下,允许施放,否则会引发异常。

0

原因是int?只是System.Nullable<int>System.Nullable<T>就是这种类型)的简写。 short类型定义了一个明确的类型转换,但System.Nullable<T>没有任何这样的显式类型转换,因为T可以是任何其他值类型。