7

我发现使用以下内容:

TreeViewItem i = sender as TreeViewItem;
if(i != null){ ... }

比以下更容易编写和理解:

if(sender.GetType() == typeof(TreeViewItem)){
    TreeViewItem i = (TreeViewItem)sender;
    ...
}

是否有令人信服的理由使用第一个构造?

4

9 回答 9

12

在大多数情况下,我更喜欢强制转换,as因为通常如果对象的类型错误,则表明存在错误。错误应该导致异常 IMO - 并且执行转换的行比代码中的后面InvalidCastException要清晰得多。NullReferenceException

as当传递了对您不想要的类型的对象的引用是有效且合法的时,应该使用它。这种情况确实会出现,但根据我的经验,它不像正常铸造那样频繁。

但是,使用 比较类型GetType()很少是正确的解决方案 - 只有当您想要检查所涉及的确切类型而不是兼容类型时才适用。

我已经在其他地方写了一个关于“cast vs as”讨论的更长的答案。

于 2009-02-20T13:22:24.527 回答
7

一点也不 - 它让您有机会验证转换(转换)是否完成。如果你这样做

TreeViewItem i = (TreeViewItem) sender;

如果强制转换失败,您可能会遇到异常。

于 2009-02-20T13:14:39.617 回答
6

一般来说,这两个片段是等价的。TreeViewItem i = sender as TreeViewItem即使sender是 的孙子,也会产生正确的结果TreeViewItem,而sender.GetType() == typeof(TreeViewItem)仅当是true 没有任何可能的子类时。senderTreeViewItem

于 2009-02-20T13:20:51.613 回答
4

“如”:好东西。一直使用它。

如果您真的想要手动比较类型的替代方法,请尝试:

  if(person is Employee) { }

读起来更好。

于 2009-02-20T13:17:07.863 回答
4

你的例子最好写成:

if (sender is TreeViewItem) {
    TreeViewItem i = (TreeViewItem)sender;
    ...
}

as操作员可以帮助避免的正是这种双重类型的检查。因此,对于您引用的示例,我会说这绝对是一个很好的解决方案。

但是,在某些情况下您确实需要演员表。如果你期待 a并且什么都不想要,那么如果你得到其他TreeViewItem任何东西,强制转换将确保抛出 an 。InvalidCastException

就像在大多数情况下一样,这里没有一揽子规则:为正确的工作使用正确的工具

于 2009-02-20T13:18:04.320 回答
2

如果您想要一个普通(不可为空)的值类型,显然这不起作用,例如:

int test = sender as int;

无效,但是:

int? test = sender as int?;

被允许。

于 2009-02-20T13:20:40.210 回答
1

“as”更快,但要记住的是:

  • 如果有问题,“as”会返回 null 而不是抛出异常

  • 它不会进行自定义转换 iirc

  • 它不适用于参考-> 价值

编辑:“as”肯定更快(http://www.codeproject.com/KB/cs/csharpcasts.aspx

Edit2:所以基本上是速度与安全的决定

于 2009-02-20T13:17:35.770 回答
1

不,我经常使用它。它允许您以干净的方式避免InvalidCastExceptions。

例如:

TreeViewItem tvItem = sender as TreeViewItem;

if (tvItem != null) return;

// Do stuff

相对于:

try
{
    TreeViewItem tvItem = (TreeViewItem)sender;
    // Do stuff.
}
catch (InvalidCastException ex)
{
    // Didn't work, do something about it
    return; // ... or not...
}
于 2009-02-20T13:17:48.687 回答
1

如果获取错误的类型是一个错误,那么您应该使用强制转换。这样做的原因是确实存在问题,您应该知道它。

如果该值可能为空,并且在发生这种情况时这不是系统中的错误,则使用“as”。原因是您应该在任何时候使用“as”来获取空值是可以接受的。

请记住,您不能使用“as”来转换为值类型,因为 null 值对它们来说是不可接受的。如果你有一个值类型并且想要使用“as”,你将需要使用一个可以为空的值类型。

何时使用“as”与铸造

于 2009-02-20T13:33:28.837 回答