为什么.ToString()在空字符串上会导致空错误,当.ToString()在具有空值的可空int上正常工作?

时间:2012-07-12 07:20:29

标签: c# string null int nullable

selectedItem有两个字段:

  • int? _cost
  • string _serialNumber

在此示例中,_cost的{​​{1}}和_serialNumber均为空。我正在通过他们的属性阅读selectedItem的字段,并在文本框中填写其值,以及......

selectedItem

我理解TextBox1.Text = selectedItem.Cost.ToString(); //no error TextBox2.Text = selectedItem.SerialNumber.ToString(); //error 是多余的(因为它已经是一个字符串),但我不明白为什么会导致这个异常:

  

Nullable对象必须有值。

  • SerialNumber.ToString()可以为空,并且没有值,但它没有给我例外。
  • int? _cost可以为空,并且没有值,但确实给我例外。

这个question触及它,这个家伙基本上是在问同样的事情,但是没有指定的答案,也没有解释为什么可以为空string _serialNumber?例如,我可以在可空int上使用int但不能在空字符串上使用吗?

8 个答案:

答案 0 :(得分:89)

因为string类型的null确实没有指向任何内容,所以内存中没有任何对象。
int?类型(可为空)即使值设置为{{仍然指向某个对象。
如果你读过Jeffrey Richter的“CLR via C#”,你会发现可空类型只是普通类型的外观类,带有一些封装逻辑以便使用DB null工作更方便。

检查msdn以了解可空类型。

答案 1 :(得分:32)

Nullable<int>struct,实际上不能为空。因此,对“null”结构的方法调用仍然有效。

有一些“编译器魔术”使_cost == null成为有效的表达式。

答案 2 :(得分:14)

int?实际上并不是一个对象,但它是一个Nullable<int>对象。

因此,当您声明int? _Cost时,您实际上声明Nullable<int> _Cost_Cost.Value的属性为undefined而不是_Cost对象本身。

  

使用non nullableintbool之类的decimal类型实际上是一种语法糖。

根据MSDN

  

语法T?System.Nullable<T>的简写,其中T是值类型。这两种形式是可以互换的。

答案 3 :(得分:4)

字符串是引用类型,但可以为null的int是值类型。以下是对差异http://www.albahari.com/valuevsreftypes.aspx的良好讨论。

答案 4 :(得分:2)

Nullable实际上是一个暴露两个属性的结构:HasValue和Value。如果你这样做,你会收到错误:

int? i = null;
i.Value.ToString()

为了检查你的int?有一个值,你可以访问i.HasValue

答案 5 :(得分:1)

我认为原因是,当编译器遇到它包装它的原始数据类型时,它到相应的对象。 toString()方法调用只是一个间接调用(包装然后调用方法),并在那里处理异常。 在String的情况下,我们直接调用该方法。当指向null时,该方法抛出异常。

答案 6 :(得分:1)

原因很简单。 int?Nullable<int>结构value type永远不能为空

那么当我们这样做时会发生什么:

int? _cost = null;

_cost将有两个字段ValueHasValue,当我们将null分配给_cost时,其HasValue标记将设置为{在false Value default(T)的情况下,int? 0字段将被分配ToString

现在,当我们在_cost上致电Nullable<T>时,ToString的覆盖定义为public override string ToString() { return HasValue ? value.ToString() : ""; } ,如果我们查看Microsoft's provided Source Reference,则执行方式如下:< / p>

_cost

因此它返回一个空字符串,因为null被分配了string _serialNumber

现在出现string的情况。作为null,它是一种引用类型,它可以纯粹持有null。如果它持有ToString,则在其上调用{{1}}将产生预期的空引用异常。

您可能会看到:Value Types and Reference Types - MSDN

答案 7 :(得分:0)

TextBox2.Text = selectedItem.SerialNumber.ToString(); //error

yiels错误,因为它调用函数ToString(),它是 System.String 的成员。此函数返回此System.String实例;没有执行实际转换。此外,String是引用类型。引用类型包含指向另一个保存数据的内存位置的指针。

TextBox1.Text = selectedItem.Cost.ToString(); //no error

不会产生任何错误,因为它正在调用函数ToString(),它是 System.Integer 的成员。此函数将此实例的数值转换为其等效的字符串表示形式。此外,Integer是一种值类型。如果数据类型将数据保存在自己的内存分配中,则数据类型是值类型。

相同的函数名称ToString()但执行不同的任务。

String.ToString Method

Int32.ToString Method

Value types and reference types