为什么我可以安全地转换为 int,但不能强制转换为 int?

3
为什么这个可以工作:
ComboBox cb = sender as ComboBox;
int validSelection = Convert.ToInt32(cb.Tag);
if (cb.SelectedIndex != validSelection) {
    cb.SelectedIndex = validSelection;
}

...但是这个:

ComboBox cb = sender as ComboBox;
int validSelection = (int)cb.Tag; // <-- fails
if (cb.SelectedIndex != validSelection) {
    cb.SelectedIndex = validSelection;
}

当出现“对象没有设置为对象的引用”错误时,该怎么办?


1
标签的实际类型是什么? - Andrei Schneider
@AndreiSchneider 对象 - asawyer
1
你要将“Tag”设置为什么? - James Michael Hare
标签是对象。发送者实际上是一个组合框吗? - Blorgbeard
是的,发送者是ComboBox。我将它们的SelectedIndex属性赋值给它们自己的Tag属性。 - B. Clay Shannon-B. Crow Raven
6个回答

13

这是因为类型转换和强制类型转换不是同一件事

cb.Tag 可能是一个 string,而不是一个 int,它们之间不能直接进行转换。 Convert.ToInt32() 实际上将解析 string 并创建一个新的 int 带有转换后的值。

强制类型转换只会尝试将一个类型实例解释为另一个类型的实例。


4
实际上,cb.Tag 声明为 object(但在此问题中很可能是一个字符串)。 - Thomas Levesque
SelectedIndex 看起来像是一个整数,但也许不是:comboBoxPlatypusID.Tag = comboBoxPlatypusID.SelectedIndex; - B. Clay Shannon-B. Crow Raven
@Clay,现在我有点困惑了,既然SelectedIndex本身就可以轻松获取,为什么要将其存储到Tag中呢? - Frédéric Hamidi
@Frederic:我使用它来将组合框的选定索引设置回其原始选定索引,如果用户在表单处于“只读状态”时尝试更改它。当设置选定索引时,我将标记值设置为相同的值。这是针对表单处于“只读”状态时查看数据库中现有值的情况。由于同一表单有时也作为可编辑表单,因此它会被设置为不同的状态...好吧,你可能已经明白了。 - B. Clay Shannon-B. Crow Raven
@Clay,是的,我认为现在更清楚了。我建议您寻找不将“Tag”设置为“SelectedIndex”的代码路径,但仍然在问题后执行代码。在这种情况下,您将把“null”转换为“int”(“Tag”是一个默认为“null”的“object”,如果未分配,则会解释为“NullReferenceException”,正如其他人在他们的答案中所解释的那样。 - Frédéric Hamidi
这比较复杂。C#的强制转换运算符也执行转换。(string)42(int)"42"是非法的事实更多地是设计决策,而不是强制转换语法的固有属性。 - phoog

7

1) 根据文档所述,Convert.ToInt32(null)总是返回0。

2) 你不能将null转换为int,因为int表示一个数字。可空的int?允许包含null值。


4

装箱值类型只能被拆箱为它们实际的类型,因此如果Tag的值不是实际的int类型,则从object转换失败。此外,如果Tag的值为null,则转换失败,因为值类型不能为null。

另一方面,当使用Convert.ToInt32时,该方法会采取必要的步骤将值转换为Int32:

  • 如果是字符串,则解析它;
  • 如果是Int64,则将其拆箱为Int64,然后将其转换为Int32
  • 如果是null,则返回0
  • 等等

3

前者要求Tag有一个支持ToInt32方法的IConvertable。后者要求Tag是一个int


1

Convert方法有多个重载,可以尝试从各种数据类型进行转换,例如Convert.ToInt32(string)

将指定字符串表示形式的数字转换为等效的32位有符号整数。

您的标签可能是Convert可以处理的类型(例如字符串)。


1
一条语句说:“将内存中表示此事物的位解释为一个 [whatever](在这种情况下是 int)。”
一次转换说:“看,实际上这个东西在内存中是非常不同的,但你知道如何将其转换为我想要的结果,请这样做并返回结果。”

而且语法(typename)value可以执行类型转换和强制转换。 - phoog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接