可能的空引用异常使用“;作为“;操作人员
本文关键字:作为 操作 引用 异常 | 更新日期: 2023-09-27 18:26:58
在以下代码中:
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#行为/功能。
使用as时,如果对象无法转换(在本例中为MyObject
),则返回null
。因此,您的线路(sender as MyObject)
有可能为空。
此代码肯定会引发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个具体的不相关的条件你正试图表达。因此,它们都必须进行测试
在这种情况下,您知道发送方实际上是MyObject
。因此,使用简单的强制转换而不是as
:
if (sender == objInstance && ((MyObject)sender).SomeBoolProperty)
或者,更好的是:
if (sender == objInstance && objInstance.SomeBoolProperty)
如果强制转换无效,as运算符将返回null。如果事件发送方不属于MyObject,则(发送方为MyObject)==null。
如果objInstance被保证不为null,那么您的语句永远不会抛出NullReferenceException。但是,如果objInstance为null,它可能会抛出。
由于您可以确定sender==objInstance,因此在验证objInstance之后,只需对objInstance进行操作,而不是强制转换sender!=无效的
这是因为R#并不总是最聪明的。此外,如果sender
和objInstance
都是null
,则仍然可以获得NullReferenceException
。无论如何,既然你已经确立了他们的平等,为什么不直接使用objInstance
呢?
试试这个:
if (sender == objInstance && objInstance.SomeBoolProperty)
要摆脱歪歪扭扭:
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被传递到其他方法时,情况会变得更糟,这使得我们很难知道代码何时何地会失败。