1

在以下代码中:

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# 行为/功能。

4

6 回答 6

6

当您使用asnull时,如果无法转换对象(在本例中为) ,则返回MyObject。因此,您的行(sender as MyObject)有可能为空。

于 2013-08-09T14:56:12.973 回答
5

这段代码肯定会导致 aNullReferenceException被抛出。考虑objInstancesender具有值的情况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 个特定的不相关条件。因此,它们都必须经过测试

于 2013-08-09T15:03:42.840 回答
3

在这种情况下,您知道 sender 确实是一个MyObject. 所以使用一个简单的演员而不是as

if (sender == objInstance && ((MyObject)sender).SomeBoolProperty)

或者,甚至更好:

if (sender == objInstance && objInstance.SomeBoolProperty)
于 2013-08-09T14:58:32.413 回答
2

如果您的强制转换无效, as 运算符将返回 null。如果 Event sender 不是 MyObject,(sender as MyObject) == null。

如果 objInstance 保证不为 null,那么您的语句将永远不会抛出 NullReferenceException。但是,如果 objInstance 为空,它可能会抛出。

由于您可以确定 sender == objInstance,因此只需在验证 objInstance != null 后对 objInstance 进行操作,而不是强制转换 sender。

于 2013-08-09T14:57:31.063 回答
1

这是因为 R# 并不总是最聪明的。此外,您仍然可以获得NullReferenceExceptionif bothsenderobjInstanceare null。无论如何,既然您已经建立了它们的平等性,为什么不直接使用objInstance

试试这个:

if (sender == objInstance && objInstance.SomeBoolProperty)
于 2013-08-09T15:00:04.753 回答
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 被传递给其他方法时,情况会变得更糟,这使得很难知道代码何时何地会失败。

于 2013-08-09T15:20:29.940 回答