Whether to check for null - c#

I know that you should always check incoming params to a method for null. But what if I have this scenario with a try/catch referring to a local variable. Do I really need to check for null below? Because it's gonna catch it anyway if it's null and the next line of code tries to use the refundResponse variable:
public string DoRefund(...)
{
try
{
......
string refundTransactionID = string.Empty;
......
RefundTransactionResponseType refundResponse = transaction.DoRefund(...);
if (refundResponse != null)
refundTransactionID = refundResponse.RefundTransactionID;
.....
}
catch (Exception ex)
{
LogError(ex);
return ex.ToString();
}
}
Remember I'm talking specifically about local variables and checking those inside a method, not incoming params to a method.
All I'm asking here is do I need to check for null before setting refundTransactionID or do I just set it without the if assuming that the compiler will handle and throw if it is null which will be caught and thrown back as a string to the caller in this case.
or should it be
if (refundResponse == null)
return null;
or just take the check out completely for this local variable assignment and then since in this case I have a try/catch I'm handling any exceptions picked up by the compiler naturally by returning the exception as a string to the caller (it was not my decision to send back a string, it was a requirement by my boss...so bypass that debate for now):
refundTransactionID = refundResponse.RefundTransactionID;
ultimately the rest of the code further down the line in the method is dependent on a valid refundTransactionID.

Exceptions are for exceptional conditions. If you can check for a continuable error, do so, please!

I know that you should always check
incoming params to a method for null.
No, not necessarily. What you should specify is the contract of your method. It's perfectly acceptable (and common) to specify that you'll throw a NullPointer/NullReferenceException for a null parameter. Then you don't need any checking.
You can also check for null, but this only makes sense if you can actually handle a null usefully (e.g. substitute a default value).

You should have to check for null in that instance. Your application logic should be able to handle these kind of situations, without the need for exceptions.

An alternative to testing is the Null Object pattern. Instead of returning Null, or a valid transaction, the transaction::DoRefund() method returns a null object: an object that offers the same interface as the RefundTransactionResponseType instances, but its methods do nothing. With this there is no need to test whether for Null.
The should be used wisely as this can easily hide problems.

No you don't need to check for null, there. That opens up another question, though, do you really need to check for null in incoming parameters?
Remember: that's a behavior. You have to test that behavior.

But if you can't continue at that point let the exception propogate.

No, doesn't look like you should check for null here. And I also wouldn't check for null for ALL incoming parameters (as your description suggests).
It's also odd that you're returning a transactionID as a string OR the message of an exception. How will the caller of this method know if an exception happened?
If you really want to log the exception, how about something like this:
public string DoRefund(...)
{
try
{
return transaction.DoRefund(...).RefundTransactionID;
}
catch (Exception ex)
{
LogError(ex);
throw ex;
}
}

You should check for null rather than letting the exception handling handle it. As leppie said, exceptions are for exceptional conditions not normal flow of control. If you know what issues can occur then you should gracefully handle them.
Another thing to keep in mind is the performance impact of exceptions. When the exception is thrown the JVM has to unwind the call stack. In your example the exception is then also logged. All of this takes time and is much slower than a simple "if" check.

I'd suggest checking for the null then doing some kind of soft error handling instead of just letting it catch and throwing an error message.

It depends on what it means to your program when (refundResponse == null). If this has some meaning, then it makes sense to report a more informative error. If it should never happen and would indicate a flaw in the DoRefund method, then I think it's fine to allow the null to cause an exception later. In the latter case, I'd only have a specific check if you're suspicious of the method and whether it's behaving as it's supposed to.

Related

Do we get any benefit from adding null check if we are already using catch all Exception handler?

This is specific to .NET
I am writing a code piece where I have to use catch all exception handler. I call a series of function which may return null. I do not want to continue if any of them return null as I have an alternate but costly method to get the same result. I want to know if I should be using the series of null checks or not.
My code looks something like:
var some_info = null;
try{
var a = GetA();
if(a != null){
var b = a.GetB();
if(b != null){
var c = GetC(b);
if(c != null){
some_info = c.GetSomeInfo();
}
}
}
catch(Exception e){
// cant do anything here but I need above code to be silent
}
if(some_info == null)
some_info = GetSomeInfoFromHeavyMethod();
in C# if we try to use null reference it throws an exception so if any of the variables above will be null a NullReferenceException will be thrown. Therefore we can write the above code like
var some_info = null;
try{
var a = GetA();
var b = a.GetB();
var c = GetC(b);
some_info = c.GetSomeInfo();
}
catch(Exception e){
// cant do anything here but I need above code to be silent
}
if(some_info == null)
some_info = GetSomeInfoFromHeavyMethod();
My question is, should I use null checks here or let exception handler work here? My gut feeling says I should use the null check as it is good practice but, I have a doubt as I have to use catch all exception handler here and I already have to bear cost of try/catch block.
Yes, I would strongly advise using null checks:
It shows that you expect that the values can be null, and that that in itself is not a problem
If you ever add logging in your catch block, you can easily do so without being spammed by easily-avoidable messages
When debugging the code, you really don't want to end up with the debugger stopping for a NullReferenceException due to just not doing checks
You say that you "already have to bear cost of try/catch block" - it's not clear whether you're talking about the code readability cost or performance cost, but there's basically no performance cost for a try/catch block if no exception is thrown. Compare that with the case when an exception is thrown, which definitely has performance implications.
Ultimately, I'd consider every NullReferenceException to be a bug somewhere - it's the kind of exception that should always cause you to either add more validation (e.g. to throw ArgumentNullException) or handle the value being null. That wouldn't the case in your code.
With some refactoring you may be able to use the null-conditional operator introduced in C# 6 to reduce the code though. You might end up with:
someInfo = GetA()?.GetB()?.GetC()?.GetSomeInfo();
Exceptions are supposed to be thrown when exceptional situations occur. So, it all depends on whether you want to consider the case of a function returning null exceptional or not. There is no hard rule.
Though I would suspect that if the functions are returning null instead of throwing an exception, then a certain choice has already been made, by those who implemented those functions, that the situation is not exceptional. But of course at the place where you call these functions you may want to redefine what is exceptional and what isn't.
There is, however, a little technical issue: throwing an exception is extremely know on Microsoft's implementation of C#, (possibly also on Mono? I don't know) so we unfortunately tend to favor not considering certain situations exceptional (and therefore not throwing an exception) when the choice is borderline and performance is an issue.

Throw Ignorable Exception

How do I throw an exception that can be ignored if it isn't handled?
Say I wanted to make sure a parameter was not null, something like
if (param == null)
{
throw new ArgumentException("Param is null!");
// if the exception isn't handled in the calling code, just return
}
I don't want to mess up the code calling that method if it does happen to be passed a null parameter. However, I'd still like to throw an exception in case whoever is using it does handle the exception.
I thought about using "rethrows" somehow, but I don't think that'd work.
Could this be better done with something like Contracts?
There are two ways to handle what you want to do:
don't throw an exception. Instead just return without incurring any side effects. Of course this might not be possible to do, depending on what the purpose of your method is.
throw the exception but also make it clear in your documentation:
what exceptions are thrown
why they are thrown
then it is up to the caller to decide whether to handle the exception or let it bubble up.
Be aware that if you throw the exception and nobody handles it then whatever is calling your code will crash. This may be considered a breaking change and may not be a welcome change in behavior.
The general rule of thumb is that you should only throw exceptions:
when it matters (i.e. it is important that you communicate an error state or consequence)
when you are changing or adding value to a state or consequence
If a null parameter value really matters because you cannot function without it, then the exception also matters and the caller should not ignore it. If the null argument doesn't matter, then don't throw an exception, instead you should return an effectively null/empty/neutral response.

Safe usage of .FirstorDefault()?

When using Enumerable.FirstorDefault(), do I need to always catch the ArumentNullException that can be thrown when the collection operated on is null?
In the past I've always just done something like this:
WorkflowColorItemType associatedColor = ColorItems
.Where(ci => ci.AssociatedState == WorkflowStateStatus.NotStarted)
.FirstOrDefault();
if (associatedColor != null)
{
this.ColorItems.CurrentColor = associatedColor;
}
In the context of this code snippet, I would never expect ColorItems to be null but is it good practice to be enclosing every instance of snippets like this in try catch blocks so I can handle the off chance that the ColorItems collection might be null?
If you don't expect the collection to ever be empty, and it would be an error in your program for it to be empty, then don't use FirstOrDefault in the first place, use First. Since it's not an expected situation for you to be in you want to draw attention to the problem because it's a sign that something is wrong.
If it's entirely valid for the collection to be empty, and you want to use the first item only if there is at least one item, then using FirstOrDefault and providing a null check is fine.
Apply the same logic to the collection being null, and not empty. If it is expected that the collection be allowed to be null, then check for it using an if. If it's not expected that the collection be allowed to be null (which is generally the case for most uses of collections) then you shouldn't check, and you want the exception to be thrown as it will draw attention to the bug in the code that is supposed to populate that collection. Trying to catch the exception and move on is trying to obscure the bug which prevents you from finding and fixing it.
Yes, certainly. You need to be defensive all the time.
In fact, if associatedColor is null, that means there is something wrong, hence you need to handle it.
In fact, your code used to be wrapped in a try/catch block to handle exceptions, since, exceptions are "expensive", this is cheaper and nicer way to handle exceptional cases.
In any case, I would almost always use FirstOrDefault or something simirlar, like SingleOrDefault then I would do the null check.
The built in LINQ functions (like .Where() here) always return an empty enumerable if there are no results, not null. So there is no need to check for null after doing the .Where()
Depending on where ColorItems comes from, you should check for null on the object:
if (ColorItems != null)
{
}
else
{
}
There's no need to put a try/catch block around the code, but you should be checking for null just to be safe. In fact, using try/catch in a scenario like this, where you can just check for a null object, is a bad programming practice.

Getting a try catch to continue 'trying' and 1st exception

I wonder if someone could give me some advice please?
I need to check for the existence of some session variables in asp.net so for instance:
try
{
zOrder = Session["epdqOrderNo"].ToString();
zAmount = Session["epdqAmount"].ToString();
zEmail = Session["epdqEmail"].ToString();
}
catch
{
}
Some or all of the session variables may exist and I'm trying to check them all but it appears that the try/catch routine goes into the catch on the first exception that it finds. So in the above example if the session variable epdqAmount doesn't exist it won't try and check for epdqEmail as its already fell out the try part. So my question is is there any way to stop this behaviour and check all of the variables or should I be using something else?
You're getting the error because Session["foo"] will return null is there is no session state variable called foo, and you can't call ToString() on a null reference.
However, you can use Convert.ToString on a null reference (in which case it will simply return string.Empty), so you could try this instead:
zOrder = Convert.ToString(Session["epdqOrderNo"]);
zAmount = Convert.ToString(Session["epdqAmount"]);
zEmail = Convert.ToString(Session["epdqEmail"]);
Using this approach, no try...catch is required because exceptions won't get thrown if any of the session variables don't exist.
You generally shouldn't try...catch in this manner, you could be potentially hiding other problems in your code. Whenever you use a try...catch try to be more specific with the exception it is you are after e.g.
try
{
}
catch (ErrorICanHandle ex)
{
}
Although in your case you would be listening for a NullReferenceException which is an indicator that you should really be checking that directly in the code as you would be effectively using exceptions to control your application flow which isn't a good idea.
As to your code, assuming all your session values are of type string then all you need is a straight cast
zOrder = (string)Session["epdqOrderNo"];
zAmount = (string)Session["epdqAmount"];
zEmail = (string)Session["epdqEmail"];
string is a special type of value type which inherits from object so this would just leave your variable as null if there is nothing in the session and not throw an exception.
try this
if(Session["MyDataSet"] == null)
{//something}
else
{//something}
In general, you'd write 3 try/catch blocks.
Couple of notes though:
You shouldn't be using a catch-all block. You might end up swallowing other important exceptions
In your particular case, there are other ways to check whether the session has those variables without throwing an exception, such as a simple null check (Session["epdqOrderNo"] == null), so I wouldn't even use try/catch here.
You can assign "" if they are null as follows using ?? as follow
zOrder = Session["epdqOrderNo"]??"";
zOrder = (string) (Session[""] ?? "");

Try Catch or If statement?

if you think there is a possibility of getting a null pointer exception, should you use an if statement to make sure the variable is not null, or should you just catch the exception?
I don't see any difference as you can put your logic to deal with the null pointer in the if statement, or in the catch block, so which one is best practise?
I would say ALWAYS use logic to catch the exception, not try/catch.
Try/Catch should be used when you validate but some strange thing happens and something causes an error so you can handle it more gracefully.
There is no single answer that will suffice here, it depends.
Let's take a few scenarios so you can see what I mean.
Scenario: Method that takes a reference type parameter that does not accept null
You're defining a method, it takes a reference type parameter, say a stream object, and you don't want to accept null as a legal input parameter.
In this case, I would say that the contract is that null is not a valid input. If some code does in fact call that method with a null reference, the contract is broken.
This is an exception, more specifically, it's an ArgumentNullException.
Example:
public void Write(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
...
I would definitely not just let the code execute until it tries to dereference the stream in this case, instead crashing with a NullReferenceException, because at that point I lost all ability to react when I know the cause.
Q. Why can't I return false instead of throwing an exception?
A. Because a return value is easy to silently ignore, do you really want your "Write" methods to just silently skip writing because you made a snafu in the calling code, passing the wrong stream object or something that cannot be written to? I wouldn't!
Scenario: Method returns a reference to an object, sometimes there is no object
In this case the contract is that null is a legal result. In my opinion, null is something to avoid because it is quite hard to make sure you handle correctly everywhere, but sometimes it is the best way.
In this case I would make sure to if my way around the result, to ensure I don't crash when the null reference comes back.
Generalisation
If you take a close look at the above two scenarios, you'll note one thing:
In both cases it comes down to what is being expected, what the contract is.
If the contract says "not null", throw an exception. Don't fall back to the old-style API way of returning false because an exceptional problem should not be silently ignored, and littering the code with if statements to ensure every method call succeeds does not make for readable code.
If the contract says "null is entirely possible", handle it with if statements.
Advertising
For getting a better grip on null problems, I would also urge you to get ReSharper for you and your team, but please note that this answer can be applied to any type of exception and error handling, the same principles applies.
With it comes attributes you can embed into your project(s) to flag these cases, and then ReSharper will highlight the code in question.
public void Write([NotNull] Stream stream)
[CanBeNull]
public SomeObject GetSomeObject()
To read more about the contract attributes that ReSharper uses, see
ReSharper NullReferenceException Analysis and Its Contracts
Contract Annotations in ReSharper 7
Well. Exceptions are just that. Exceptions. They are thrown when something unforseen has happened and should not be part of the normal program flow.
And that's what is happening here. You expected the argument to be specified when it's not. That is unexpected and you should therefore throw your own exception informing the user of that. If you want to get bonus points you can also include the reason to WHY the argument must be specified (if it's not obvious).
I've written a series of posts about exceptions: http://blog.gauffin.org/2013/04/what-is-exceptions/
From a performance standpoint it really depends what you're doing. The performance impact from a try/catch block when no exception is thrown is minimal (and if you really need that last few percent of performance, you probably should rewrite that part of your code in C++ anyway). Throwing exceptions does have a major impact on simpler operations such as string manipulation; but once you get file/database operations in the loop they're so much slower that again it becomes a trivial penalty. Throwing across an App Domain will have a non-trivial impact on just about anything though.
Performance in Operations/second:
Mode/operation Empty String File Database Complex
No exception 17,748,206 267,300 2,461 877 239
Catch without exception 15,415,757 261,456 2,476 871 236
Throw 103,456 68,952 2,236 864 236
Rethrow original 53,481 41,889 2,324 852 230
Throw across AppDomain 3,073 2,942 930 574 160
Additional test results along with the source for the tests is available from the article Performance implications of Exceptions in .NET
I would rather suggest you use if-statement for NullReference exception. For other exception, try-catch should be good enough.
The reason I suggest if-statement for NullReference exception is because C# will not tell which variable is null. if that line has more than one object could be null, you will loss track. If you are using if-statement, you can have better logging to help you get the enough information.
The main Question is if it is a good idea to have methods returning Null at all, personally i do not have any problem with this, but as soon as you try to access modifiers of an object returned from this method and you forget to check if it is assigned this becomes an issue.
Ken has a good answer about this:
If you are always expecting to find a value then throw the exception
if it is missing. The exception would mean that there was a problem.
If the value can be missing or present and both are valid for the
application logic then return a null.
See this disscussion abou tthis issue:
Returning null is usually the best idea if you intend to indicate that
no data is available.
An empty object implies data has been returned, whereas returning null
clearly indicates that nothing has been returned.
Additionally, returning a null will result in a null exception if you
attempt to access members in the object, which can be useful for
highlighting buggy code - attempting to access a member of nothing
makes no sense. Accessing members of an empty object will not fail
meaning bugs can go undiscovered.
Some further reading:
No Null Beyond Method Scope
Should We Return Null From Our Methods?
using try catch for the statements is not an good idea. because when you use try catch them it seems that if some error comes the code will not turninate the application. but if you are sure about what kind of error can come you can tap the error at that point. that will not produce any unknown errors. for example.
string name = null;
here i am going to use the name variable and i am sure that this will throw Null Refrance Error .
try
{
Console.writeLine("Name ={0}",name);
}
catch (NullRefranceException nex)
{
//handle the error
}
catch(Exception ex)
{
// handle error to prevent application being crashed.
}
This is not a good practice while you can handle this kind of error and make your code more readable. like.
if(name !=null)
Console.writeLine("Name ={0}",name);
In my experience using if is better but only if you actually expect a null reference pointer. Without any bit of code or context its difficult to say when one option is better than the other.
There's also a matter of optimization - code in try-catch blocks won't be optimized.
In general, try-catch blocks are great because they will break (move to the catch statement) whenever the exception occurs. If-else blocks rely on you predicting when the error will happen.
Also, catch blocks won't stop your code from halting when an error is hit.
Its always better to use Try Catch other than if else
Here Exceptions are two types namely handled and UN-handled exceptions
Even if u want to handle some function when the Exception u can handle it...
Handled exception always allows you to write some implementations inside the Catch block
Eg. An Alert Message, A new Function to handle when such exception occurs.

Categories

Resources