我总是对何时使用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
判断的风格?
答案 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)通常足以在调试器/单元测试结果中捕获异常。