我发现使用以下内容:
TreeViewItem i = sender as TreeViewItem;
if(i != null){ ... }
比以下更容易编写和理解:
if(sender.GetType() == typeof(TreeViewItem)){
TreeViewItem i = (TreeViewItem)sender;
...
}
是否有令人信服的理由不使用第一个构造?
我发现使用以下内容:
TreeViewItem i = sender as TreeViewItem;
if(i != null){ ... }
比以下更容易编写和理解:
if(sender.GetType() == typeof(TreeViewItem)){
TreeViewItem i = (TreeViewItem)sender;
...
}
是否有令人信服的理由不使用第一个构造?
在大多数情况下,我更喜欢强制转换,as
因为通常如果对象的类型错误,则表明存在错误。错误应该导致异常 IMO - 并且执行转换的行比代码中的后面InvalidCastException
要清晰得多。NullReferenceException
as
当传递了对您不想要的类型的对象的引用是有效且合法的时,应该使用它。这种情况确实会出现,但根据我的经验,它不像正常铸造那样频繁。
但是,使用 比较类型GetType()
很少是正确的解决方案 - 只有当您想要检查所涉及的确切类型而不是兼容类型时才适用。
我已经在其他地方写了一个关于“cast vs as”讨论的更长的答案。
一点也不 - 它让您有机会验证转换(转换)是否完成。如果你这样做
TreeViewItem i = (TreeViewItem) sender;
如果强制转换失败,您可能会遇到异常。
一般来说,这两个片段是不等价的。TreeViewItem i = sender as TreeViewItem
即使sender
是 的孙子,也会产生正确的结果TreeViewItem
,而sender.GetType() == typeof(TreeViewItem)
仅当是true
且没有任何可能的子类时。sender
TreeViewItem
“如”:好东西。一直使用它。
如果您真的想要手动比较类型的替代方法,请尝试:
if(person is Employee) { }
读起来更好。
你的例子最好写成:
if (sender is TreeViewItem) {
TreeViewItem i = (TreeViewItem)sender;
...
}
as
操作员可以帮助避免的正是这种双重类型的检查。因此,对于您引用的示例,我会说这绝对是一个很好的解决方案。
但是,在某些情况下您确实需要演员表。如果你期待 a并且什么都不想要,那么如果你得到其他TreeViewItem
任何东西,强制转换将确保抛出 an 。InvalidCastException
就像在大多数情况下一样,这里没有一揽子规则:为正确的工作使用正确的工具。
如果您想要一个普通(不可为空)的值类型,显然这不起作用,例如:
int test = sender as int;
无效,但是:
int? test = sender as int?;
被允许。
“as”更快,但要记住的是:
如果有问题,“as”会返回 null 而不是抛出异常
它不会进行自定义转换 iirc
它不适用于参考-> 价值
编辑:“as”肯定更快(http://www.codeproject.com/KB/cs/csharpcasts.aspx)
Edit2:所以基本上是速度与安全的决定
不,我经常使用它。它允许您以干净的方式避免InvalidCastException
s。
例如:
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...
}
如果获取错误的类型是一个错误,那么您应该使用强制转换。这样做的原因是确实存在问题,您应该知道它。
如果该值可能为空,并且在发生这种情况时这不是系统中的错误,则使用“as”。原因是您应该在任何时候使用“as”来获取空值是可以接受的。
请记住,您不能使用“as”来转换为值类型,因为 null 值对它们来说是不可接受的。如果你有一个值类型并且想要使用“as”,你将需要使用一个可以为空的值类型。