在编写API时使用if(obj==null)的位置

  • 本文关键字:obj null 位置 if API 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判断的风格吗?

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

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

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

稍后,检查null:

  • 在公共或受保护的联系人中,如果特定的方法参数或返回值必须不是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:

  • 在私人联系人中,当值不能为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) 通常,在调试器/单元测试结果中捕获异常就足够了。

最新更新