简体   繁体   中英

Where to use if(obj == null) When writing API?

I am always confused about when to use if (sth == null) . Design of delegate in C# is like this:

//Declaration:
private delegate void OnSthHappened();

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

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

I really think of judging it is null everytime when use OnSthHappened is unnecessary. I know that in compiler, delegate will become a class to handle the callback. Then why the C# compiler doesn't do the other way like:

//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);
}

I just gave a scene of where to judge null, this is giving me hard choices everytime when I try to write API, to do ==null in caller or called functions? Does anyone could give me some style about where to use ==null judgement?

I know that in compiler, delegate will become a class to handle the callback

Delegate (more precise, MulticastDelegate , because in fact we work with multicast delegates) is a class already. The delegate keyword is just a way to declare a MulticastDelegate -derived type.

Where to use if(obj == null) When writing API?

Shortly, check for null :

  • in public or protected contacts, if the particular method parameter or return value must not be null . If it is null, throw an exception;
  • in public, protected or private contracts, when value the value could be null, and you can handle that.

     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(); } 

Do not check for null :

  • in private contacts, when value must not be null.

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

UPD .

why use different strategies between private and public methods? What is the benefit?

Public or protected surface is unpredictable.
You can't guarantee, that user of your class will provide, for example, valid parameter values. That's why you must check them - this is the way to tell the user, that something is wrong in his code. By delivering understandable exception, you can tell, what is wrong exactly . Note, that user hasn't access to your code, and ArgumentNullException on your method call is much more cleaner, that NullReferenceException inside of your method.

On the other hand, your release code should be clean from extra checks.
If you'll return null from any private method, and then try to access a member of that null value, you'll get NRE during debugging or testing. Then you have to fix error in your code and forget it. If you have fixed the error, there's no reason to keep the null -checking alive. This all doesn't avoid Debug.Assert / Contract.Assert or similar. But: a) those thing should live in debug version of your code; b) they must not be after every line of code, because this reduces code readability; c) often it is enough to catch an exception in debugger/unit test result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM