双倍和双倍?互换?

问题描述:

如上 - 有人知道一个double是否被隐式转换为double? (Nullable type)双倍和双倍?互换?

编辑:这里究竟发生了什么?

double d = 5;

double? d2 = d为双?

+0

请参阅http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx和http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx – Brian 2010-02-10 23:55:14

+0

为什么不写“双? d = 1.0;“在你的IDE中,看看它是否编译? – 2010-02-11 00:19:07

+0

从§6.1.4(隐式可空转换):“对于从不可空值类型'S'转换为不可空值类型'T'的每个预定义隐式标识和数值转换,以下隐式存在可为空的转换:[...]•从'S'到'T?'的隐式转换。“ 'double'扮演'S'角色,'double'扮演'T'的角色(都是不可空的),并注意到有一个从double('S')到'double'的隐式转换'T'),通过上面的子句,存在从'double'('S')到'double?'('T?')的隐式转换。 – jason 2010-02-11 03:22:25

double d = 5; 
double? d2 = d as double?; 

那么,让我们通过它去。

在第一行中,您声明了一个名为d的类型为double的局部变量。您为其分配恒定的整数5。编译器将常量整数5转换为双精度值5.0,并生成将值分配给本地的代码。

在第二行中,您声明了一个名为d2的局部变量double ?.

表达式“d as double?”相当于“d是double??(double?)d:(double?)null”,当然除了“d”只被评估一次。

读取“d”的部分是双倍的?“被评估为真,因为d被认为是double类型的(当被问到”x是y“时,如果x是非空类型,而y是相应的可空类型,那么结果总是为真。)

编译器知道这一点,因此丢弃替代“(双?)空”,因此产生的代码,就好像你说

double? d2 = (double?)d; 

这是产生通过调用双?,传球的构造在d中作为构造函数的参数,并且将局部变量d2作为“this”的引用。因此,本质上变成:

double? d2 = new Nullable<double>(d); 

那就是究竟是那里发生了什么。这一切都有道理吗?

+0

Eric:当你这样做的时候,编译器不会抱怨吗? d2 = d;?隐式强制转换调用构造函数是否正常? – 2010-02-12 12:01:30

+0

@ChloeRadshaw:适用于涉及价值类型的转化。你将int转换为double,我们构造一个新的double。当然,double的“构造函数”是IL中的单个指令,但这是一个实现细节。 – 2010-02-12 15:10:59

是的,double被隐式转换为double?。例如。如果ddouble那么double? nullableD = d;是好的。

尽管double?未隐式转换为double。在这种情况下,您应该使用double d = nullableD.Value;

+0

您也可以使用强制转换,但如果它为空则会抛出异常。 – Brian 2010-02-10 23:48:59

+0

你应该只在使用nullableD.value之后检查nullableD是否为空。 – 2010-02-10 23:49:00

+0

@Paul:除非您对异常感到满意,否则只需使用Value即可。 – 2010-02-10 23:50:58

它们根据您的标题不可互换。

有一个隐含double转换为double?

有一个明确转换从double?double

这同样适用于所有的空值类型真:有一个隐式转换从TNullable<T>,并从Nullable<T>T明确的一个。

有趣的是,虽然Nullable<T>确实提供了这些转化为以正常的方式用户定义的转换,则MS C#编译器不使用的那些 - 它调用Nullable<T>(T value)构造为隐式转换,并直接使用Value属性为反过来显式转换。

+0

@Jon:你下班或在家工作? :) – Perpetualcoder 2010-02-10 23:49:20

+0

@Perpetualcoder:现在是在英国下午11点50分 - 我即将上床睡觉:) – 2010-02-10 23:50:33

+0

@Jon:在你碰到床之前捡起几百个代表点:) – Perpetualcoder 2010-02-10 23:58:08

,您可以在如下

double? d; 
    d = 12.00  
    double d2 = (double)d; 

小心你投为双过吗?可能为null;究竟这是怎么回事就更好做此项检查


if(d.HasValue) 
    { double d2 = (double)d; } 
+1

只有手动检查值是否为空而不是由于错误或其他某种情况应该引起异常。 – 2010-02-10 23:51:45