为什么。在空字符串上使用 ToString()会导致空错误。ToString()在一个带空值的可空整型上可以正常工作吗?

selectedItem有两个字段:

  • int? _cost
  • string _serialNumber

在本例中,selectedItem_cost_serialNumber都为空。我通过它们的属性阅读 selectedItem的字段,并用它们的值填充文本框,当..。

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

我知道 SerialNumber.ToString()是多余的(因为它已经是一个字符串) ,但我不明白为什么会出现这种异常:

可为空的对象必须有一个值。

  • int? _cost是可空的,没有值,但是它没有给我异常。
  • string _serialNumber是可空的,没有值,但是它 是的给了我一个异常。

这个 有个问题碰到了它,这个家伙本质上是在问同样的问题,但是没有指定的答案,而且它也没有解释为什么一个可以为零的 int?例如,我可以在一个可以为空的 int 上使用 .ToString(),但是不能在一个空字符串上使用 .ToString()吗?

10868 次浏览

Nullable<int>struct,不能真正为 null。因此对“ null”结构的方法调用仍然可以工作。

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

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

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

为了检查 int? 是否有值,您可以访问 i.HasValue

因为 string类型的 null实际上没有指向任何东西,所以内存中没有任何对象。< br/> 但是 int? type (nullable)即使值设置为 null仍然指向某个对象。< br/> 如果你读过 Jeffrey Richter 的“ CLR via C #”,你会发现可空类型只是一些带有封装逻辑的常见类型的 facade 类,目的是为了使使用 DB null 更加方便。

检查 我不知道以了解可空类型。

实际上,int?本身并不是一个对象,而是一个 Nullable<int>对象。

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

它实际上是一个句法糖使用 non nullable类型,如 intbooldecimal容易。

根据 MSDN:

语法 T?System.Nullable<T>的简写,其中 T是值类型。

我认为原因是,当编译器遇到一个原始数据类型时,它将其包装到对应的对象。ToString ()方法调用在这里只是一个间接调用(包装然后调用方法) ,异常在那里处理。 而对于 String,我们直接调用方法。当指向 null 时,该方法引发异常。

字符串是引用类型,但可空整型是值类型。这里是一个很好的讨论差异 http://www.albahari.com/valuevsreftypes.aspx

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

产生错误,因为它正在调用函数 ToString (),该函数是 系统。字符串的成员。此函数返回 System 的此实例。字符串; 不执行实际的转换。另外,String 是一种引用类型。引用类型包含一个指向另一个保存数据的内存位置的指针。

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

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

同样的函数名 ToString () ,但执行不同的任务。

ToString 方法

ToString 方法

值类型和引用类型

原因很简单,int?Nullable<int>结构值类型它永远不会是无效的

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

int? _cost = null;

_cost将有两个字段 ValueHasValue,当我们将 null分配给 _cost时,它的 HasValue标志将被设置为 false,而 Value字段将被分配 default(T),如果 int?它将被分配 Value0。

现在,当我们在 _cost上调用 ToString时,Nullable<T>有一个 ToString的覆盖定义,如果我们看看 微软提供的源代码参考的实现,就会发现:

public override string ToString() {
return HasValue ? value.ToString() : "";
}

因此它返回一个空字符串,因为 _cost被赋值为 null

现在是 string _serialNumber的情况。作为 string它是一个参考类型,它可以 纯粹的举行 null。如果它持有 null,那么对它调用 ToString将产生预期的 Null 引用异常。

你可以看到: 值类型和引用类型