在以下代码中:
MyObject objInstance;
private void someEventHandler(object sender, EventArgs e)
{
if (sender == objInstance && (sender as MyObject).SomeBoolProperty)
// Do Something
}
Resharper警告sender as MyObject
可能是NullReferenceException。这个代码可以吗?我假设如果sender == objInstance
(sender as MyObject)
不会返回null,但这不是Resharper消息第一次通知我C#行为/功能我不知道。< / p>
答案 0 :(得分:6)
当您使用as时,如果无法转换对象(在本例中为null
),则会返回MyObject
。因此,您的行(sender as MyObject)
可能为空。
答案 1 :(得分:5)
此代码肯定会导致NullReferenceException
被抛出。考虑objInstance
和sender
具有值null
的情况。在这种情况下,sender == objInstance
将为true
,因为null == null
因此sender as MyObject
也将返回null
,代码将抛出属性访问
编写该代码的最佳方法是
var senderObj = sender as MyObject;
if (senderObj != null &&
senderObj == objInstance &&
senderObj.SomeBoolProperty) {
// Do something
}
不幸的是,我不相信有一种方法可以显着简化这段代码。您尝试表达的3个特定的无关条件。因此,他们必须全部进行测试
答案 2 :(得分:3)
在这种情况下,您知道发件人确实是MyObject
。因此,请使用简单的强制转换而不是as
:
if (sender == objInstance && ((MyObject)sender).SomeBoolProperty)
或者,甚至更好:
if (sender == objInstance && objInstance.SomeBoolProperty)
答案 3 :(得分:2)
如果您的演员表无效,则as运算符返回null。如果事件发件人不是MyObject,(发件人为MyObject)== null。
如果保证objInstance不为null,那么您的语句将永远不会抛出NullReferenceException。但是,如果objInstance为null,则可能抛出。
由于您可以确定sender == objInstance,因此在验证objInstance!= null之后,只需对objInstance进行操作而不是强制转发发送者。
答案 4 :(得分:1)
这是因为R#并不总是最聪明的。此外,如果NullReferenceException
和sender
都是objInstance
,您仍然可以获得null
。无论如何,当你建立了他们的平等时,为什么不使用objInstance
?
请改为尝试:
if (sender == objInstance && objInstance.SomeBoolProperty)
答案 5 :(得分:0)
摆脱波浪形的:
MyObject objInstance;
private void someEventHandler(object sender, EventArgs e)
{
var myObj = sender as MyObject;
Debug.Assert(myObj != null);
if (sender == objInstance && myObj .SomeBoolProperty)
// Do Something
}
R#理解断言,并会停止警告你。而且,自由插入这些调试断言并不是一种不好的做法。无论何时接收引用类型作为public
方法的参数,我都会断言该值不为null,或者在某些情况下抛出异常专门用于接收null参数而不是等待代码失败再向下。当null被传递到其他方法时会变得更糟,这使得很难知道代码将在何时何地失败。