.ToString() 不会引发双重异常?还是长?虽然它会在空字符串上引发异常

Posted

技术标签:

【中文标题】.ToString() 不会引发双重异常?还是长?虽然它会在空字符串上引发异常【英文标题】:.ToString() does not raise an exception on double? or long? while it will raise an exception on null string 【发布时间】:2015-07-27 14:26:42 【问题描述】:

我有以下三个属性:-

public Nullable<double> SPEED  get; set; 
public Nullable<Int64> PROCESSORCOUNT  get; set; 
public string CPUNAME  get; set; 

现在在我的 asp.net mvc5 web 应用程序的控制器类中,如果我为上述三个变量传递 null,如下所示:-

query["proSpeed"] = sj.SPEED.ToString();
query["proCores"] = sj.PROCESSORCOUNT.ToString();
query["proType"] = sj.CPUNAME.ToString();

然后 toString() 只会在空字符串上引发异常,主要是 sj.CPUNAME.ToString();,所以如果我尝试转换包含空的 double?long?,任何人都可以知道为什么 ToString() 不会引发异常值到字符串,但只有当字符串为空时才会引发空引用异常?

【问题讨论】:

但是如果变量类型是字符串,为什么要 ToString() 呢? 【参考方案1】:

为了简化:

int? x = null;
string result = x.ToString(); // No exception

这里的null 不是空的引用。它只是int? 类型的空值,即Nullable&lt;int&gt; 类型的值,其中HasValue 为假。

您只是在该值上调用Nullable&lt;T&gt;.ToString() 方法。不涉及空引用,因此没有NullReferenceException。该行为记录为:

如果HasValue 属性为真,则为当前Nullable&lt;T&gt; 对象的值的文本表示形式;如果HasValue 属性为假,则为空字符串("")。

换句话说,它被有效地实现为:

return HasValue ? Value.ToString() : "";

请注意,这仅在 编译时类型 是可空类型时才有效。

如果你最终装箱一个空值,你最终会得到一个空引用:

object y = x;               // Oh noes, now y is a null reference...
string bang = y.ToString(); // so this throws!

【讨论】:

所以在你的例子中 x.ToString 将返回实际返回空字符串而不是实际的 null ? @johnG:是的。自己测试一下 - Console.WriteLine(x.ToString().Length);【参考方案2】:

Nullable&lt;T&gt; 本身不能为空,它的值可以。例如,您可以将其ToString 方法实现为:

public string override ToString()

     if (this.HasValue) return this.Value;
     else return string.Empty;

您不能对string 做同样的事情,因此如果字符串为空,则会引发NullReferenceException

【讨论】:

【参考方案3】:

MSDN Help 对此非常清楚。

当前 Nullable 对象的值的文本表示 如果 HasValue 属性为 true,或者如果 HasValue 属性为 false。

【讨论】:

以上是关于.ToString() 不会引发双重异常?还是长?虽然它会在空字符串上引发异常的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 异常不会引发

为啥我的信号处理程序(引发异常)不会多次触发?

如果在生成 std​​::thread 后引发异常,则不会捕获异常

在 C# 中添加 long/ulong SSE 不会引发溢出异常?

为啥 QNAN == QNAN 不会导致引发 FE_INVALID 异常?

将另一个对象传递给当前的休息服务不会引发异常