C# 为什么空字符串上的.ToString()会导致空错误,而.ToString()在具有空值的可空int上运行良好?
C# 为什么空字符串上的.ToString()会导致空错误,而.ToString()在具有空值的可空int上运行良好?,c#,string,null,int,nullable,C#,String,Null,Int,Nullable,selectedItem有两个字段: int_成本 string\u serialNumber 在本例中,selectedItem的\u cost和\u serialNumber均为空。我正在通过它们的属性读取selectedItem的字段,并在文本框中填入它们的值,这时 TextBox1.Text = selectedItem.Cost.ToString(); //no error TextBox2.Text = selectedItem.SerialNumber.ToString();
selectedItem
有两个字段:
int_成本
string\u serialNumber
selectedItem
的\u cost
和\u serialNumber
均为空。我正在通过它们的属性读取selectedItem
的字段,并在文本框中填入它们的值,这时
TextBox1.Text = selectedItem.Cost.ToString(); //no error
TextBox2.Text = selectedItem.SerialNumber.ToString(); //error
我知道SerialNumber.ToString()
是多余的(因为它已经是一个字符串),但我不明白为什么会出现这种异常:
可为null的对象必须有一个值
可以为null,并且没有值,但它不会给我异常int_cost
可以为空,并且没有值,但是它会给我一个异常string\u serialNumber
int
?例如,我可以在可为null的int上使用.ToString()
,但不能在null字符串上使用吗?可为null的是一个结构,不能真正为null。因此,对“null”结构的方法调用仍然有效
有一些“编译器魔法”使\u cost==null
成为一个有效的表达式。可null实际上是一个公开两个属性的结构:HasValue和Value。如果您这样做,您将得到错误:
int? i = null;
i.Value.ToString()
为了检查你的int是否正确?有一个值你可以访问i.HasValue,因为string
type的null
实际上没有指向任何对象,所以内存中没有任何对象。
但是int?
type(null)即使值设置为null
仍然指向某个对象。
如果你阅读杰弗里里克特的“CLR via C#”您将发现,可为null的类型只是带有一些封装逻辑的普通类型的门面类,以便更方便地使用DB null
检查以了解可为空的类型。int?
本身实际上不是一个对象,但它是一个可为空的对象
那么当你声明int_Cost
,您实际上是在声明可空的\u Cost
,而\u Cost.Value的属性是未定义的而不是\u Cost
对象本身
实际上,很容易使用不可空
类型,如int
、bool
或decimal
,这是一种语法上的甜点
根据:
语法T?
是System.Nullable
的缩写,其中T
是一种值类型。这两种形式可以互换
我认为原因是,当编译器遇到一个原始数据类型时,它会将其包装到相应的对象。这里的toString()方法调用只是一个间接调用(包装然后调用该方法),异常在这里处理。
而对于String,我们直接调用方法。当指向null时,该方法抛出异常。字符串是引用类型,但可为null的int是值类型。这里是一个很好的差异讨论
yiels错误,因为它正在调用属于系统.String成员的函数。此函数返回System.String的此实例;不执行实际转换。此外,String是一种引用类型。引用类型包含指向保存数据的另一个内存位置的指针
TextBox1.Text = selectedItem.Cost.ToString(); //no error
不会产生错误,因为它正在调用属于System.Integer的函数。此函数用于将此实例的数值转换为其等效的字符串表示形式。此外,Integer是一种值类型。如果数据类型将数据保存在自己的内存分配中,那么它就是值类型
函数名ToString()相同,但执行的任务不同
原因很简单int?
或者是结构或,它永远不能为空
那么,当我们这样做时会发生什么:
int? _cost = null;
\u cost
将有两个字段Value
和HasValue
,当我们将null
分配给\u cost
时,其HasValue
标志将设置为false
,并且Value
字段将被分配默认值(T)
,如果int?
它将设置为0
现在,当我们在\u cost
上调用ToString
时,Nullable
有一个ToString
的覆盖定义,如果我们看一下,它的实现如下:
public override string ToString() {
return HasValue ? value.ToString() : "";
}
因此,它返回一个空字符串,因为\u cost
被赋值为null
现在是string\u serialNumber
的例子。作为字符串
它是一个引用类型,它可以完全保持null
。如果它保持null
,则对其调用ToString
,将产生预期的null引用异常
您可能会看到:您链接到的问题完全不同。这个问题是关于MessageBox.Show
和String.Concat
如何处理null
字符串。请注意,您使用的单词“nullable”表示两种完全不同的含义int?
是一种值类型,称为Nullable
,对空值有特殊处理string
是一种引用类型(虽然有点奇怪),它的实际值可以是null
。int?
总是有一个值,它只是有一种特殊的方式来表示“我现在的行为就像null
。”所以基本上,因为它实际上不是null,它只是假装为null?是的,基本上它是一个围绕int字段的结构,布尔符号表示这个结构是设置为int值,还是仍然单位化,这意味着零。在里面
public override string ToString() {
return HasValue ? value.ToString() : "";
}