在哪里使用if(obj == null)编写API时?

时间:2014-09-12 05:57:50

标签: c#

我总是对何时使用if (sth == null)感到困惑。 C#中委托的设计是这样的:

//Declaration:
private delegate void OnSthHappened();

//In some place, do:
OnSthHappened += SthHappendCallback;

//When use delegate:
if(OnSthHappened != null)
OnSthHappened();

我真的想到每次使用OnSthHappened时都判断它是空的。我知道在编译器中,委托将成为一个处理回调的类。那么为什么C#编译器不会这样做:

//Use the delegate directly:
OnSthHappened();

//In the created-by-compiler class, do the judgement:
//object: instance object, Intptr method: a method pointer
if(method != 0x00) //Null, hide the judgement here
{
   Invoke(object, method);
}

我刚刚给出了一个判断null的位置的场景,每当我尝试编写API,在调用者或调用函数中执行==null时,这给了我很难的选择?有谁能给我一些关于在哪里使用==null判断的风格?

1 个答案:

答案 0 :(得分:1)

  

我知道在编译器中,委托将成为处理回调的类

Delegate(更确切地说,MulticastDelegate,因为实际上我们使用多播代理)已经一个类。 delegate关键字只是一种声明MulticastDelegate派生类型的方法。

  

在哪里使用if(obj == null)编写API时?

很快,请检查null

  • 在公共联系人或受保护联系人中,如果特定方法参数或返回值不得为null。如果为null,则抛出异常;
  • 在公共,受保护或私有合同中,当值可能为空时,您可以处理它。

    public void Method1(Action action)
    {
        Contact.Requires<ArgumentNullException>(action != null);
    }
    
    public object Method2()
    {
         Contract.Ensures(Contract.Result<object>() != null);
    
         // code here
     }
    
     public void Method2(Action action == null)
     {
         if (action != null)
            action();
     }
    

不要检查null

    私人联系人中的
  • ,当值不能为空时。

    private void Method3()
    {
         var result = Method2();
         // In case of result == null, NRE is a best option here.
         Console.WriteLine(result.ToString().Length);
    }
    

<强> UPD

  

为什么在私人和公共方法之间使用不同的策略?有什么好处?

公共或受保护的表面是不可预测的 您无法保证,您班级的用户将提供有效的参数值。这就是你必须检查它们的原因 - 这是告诉用户他的代码中出错的方法。通过提供可理解的异常,您可以说出错误完全。请注意,该用户无法访问您的代码,方法调用上的ArgumentNullException更加清晰,方法内部NullReferenceException

另一方面,您的发布代码应该清除额外的检查 如果您从任何私有方法返回null,然后尝试访问该null值的成员,则在调试或测试期间您将获得NRE。然后你必须修复你的代码中的错误而忘记它。如果您已修复错误,则没有理由保持null - 检查活动。这一切都不会避免Debug.Assert / Contract.Assert或类似。但是:a)那些东西应该存在于代码的调试版本中; b)它们不得在每行代码之后,因为这会降低代码的可读性; c)通常足以在调试器/单元测试结果中捕获异常。