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
:
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.