我总是对何时使用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) 通常,在调试器/单元测试结果中捕获异常就足够了。