When to check for nulls? - c#

When you know id is suppose to exist as in the example below, is it good practice to check for nulls?
var submission = _ctx.Submissions.FirstOrDefault(p => p.Id == id);
submission.Done = true;
_ctx.Submissions.Attach(submission);
_ctx.Entry(submission).State = EntityState.Modified;
_ctx.SaveChanges();

If id is supposed to exist you do not check for null. In fact in this case you should query like this
_ctx.Submissions.Single(p => p.Id == id);
The Single method will throw an exception if the item is not found. On the other hand if you are building a WebAPI or have a specific not found page as the id is sent by the client (i.e. can result by something outside your code) you may use SingleOrDefault, then check for null and return appropriate HTTP status code or redirect to the appropriate page. Basically if null results from not validated data you should check and respond accordingly. If the arguments that cause null values are generated by code you should NOT check for null and in fact query in a way that may not result in null because otherwise you are just covering an error in your code.
This is my opinion which is a result of my personal experience. Note that not everyone agrees as is obvious by the different answers of a question I posted on programmers.stackexchange.com some time ago - https://softwareengineering.stackexchange.com/questions/147480/should-one-check-for-null-if-he-does-not-expect-null

You check for null when you cannot say with complete certainty that the object will never not be null.
With that said, you are using FirstOrDefault(). If it didn't find anything in the criteria, it will return you null.

If you feel that there should always be an object, and that there not being an object in question would mean that there is a bug in the program somewhere, then you should use First not FirstOrDefault. Doing this means that if one of your assumptions for this code ends up being violated you will be informed quickly, loudly, and as close to the source of the problem as possible.
FirstOrDefault should be used if it's entirely sensible for the query in question to have no items, resulting in a null value being returned. If you are in this position, the program should work correctly if the query does in fact return null, or whatever else you need to do for the program to function appropriately.
What you want to avoid is putting yourself in the position where a program (incorrectly) assumes a query always has at least one item, but where you use FirstOrDeafult anyway. Here you end up with NullReferenceExceptions, which can take extra debugging work to figure out where the actual problem is (a query with no items that should have had items).

For resilient code you should definitely check and handle to see if submission is null.

You check for the null values, if there is an error to be occured by passing a null value. You can check them in any way, either by using try catch block or using a an if else block.
You can check it, this way you can prevent the errors that might occur by a null value.

FirstOrDefault documents your intention as "the result I'm expecting may not contain items". In such case you should check for null and perform some reasonable fallback. Throwing exception at that point would look strange.
It sounds like in your case you don't expect empty result, so use First and handle exception somewhere higher on call stack or even let default exception handling to happen.

Related

Differentiating between the same type of Exceptions, e.g. with Enumerable.Single()

Consider the following code:
int myId = 10;
try
{
var me = this.Db.People.Single(p => p.Id = myId);
}
catch(InvalidOperationException e)
{
// Either I don't exist ("Sequence contains no elements"),
// or more than one of me exists ("Sequence contains more than one element")
}
There are two conditions: Either 0 results are returned (which might not be too alarming, the person just doesn't exist), or more than 1 result are returned (which means something is seriously wrong assuming ID is supposed to be unique).
Ideally, I would like to catch and handle the exception if it was thrown because 0 results were returned, but not catch the exception if it was thrown because more than one results were returned (I can't handle this situation, but I don't want to simply ignore something that went very wrong).
Is there a way to differentiate between the two exceptions so I can only handle the case in which 0 results are returned, or is my only option to use SingleOrDefault and check for the null?
The answer is here:
Either 0 results are returned (which might not be too alarming, the
person just doesn't exist),
This isn't "exceptional" because as you said, a person might not exist. So we shouldn't throw an exception when this happens. It's like going to a website and searching for a product. If no results are returned that's probably not an error. It just means that they don't sell that product.
or more than 1 result are returned (which means something is seriously wrong assuming ID is supposed to be unique).
If it should be impossible to get more than one result, then more than one result should throw an exception.
That makes SingleOrDefault the best choice. Check for the null, because the query might not return anything. But if something completely out of bounds happens then there should be an exception.

Why does this code segment return null under heavy load?

if (this.UserManagmentType != UserMgmtType.NONE)
{
return (User)GetUserBaseById(userId);
}
if (this.UserManagmentType != UserMgmtType.NONE)
{
return GetUserBaseById(userId) as User;
}
I understand the difference between casts. The first if statement should throw an invalid cast exception if the cast fails, while the second will return a null.
My question is, for identical data under heavy load in a multi-threaded environment, why does the first if statement occasionally return a null, while the second if statement will always return valid data?
The other item of note is that the containing method is a WCF endpoint.
Thank you for any insight.
The answer, given the code you've posted, is: it won't.
The first snippet will return null if (and only if) GetUserBaseById returns null. The second will return null if the method's return is null or if it's not a User object. That behaviour doesn't change under heavy load.
If you're seeing different results under heavy load as you describe then I'd suggest you have a multithreading issue elsewhere in your code, and it just happens that this is where you're seeing the effects. This sort of bug can be very sensitive to external conditions, and you're not guaranteed that it will reproduce the same way each time you run (because it might be sensitive to, e.g., disk contention with other processes).
I would suggest a thorough review of the multithreaded functionality in question: the problem you're seeing is not in that line of code.
Two castings are different, and as per this article
http://www.codeproject.com/Articles/8052/Type-casting-impact-over-execution-performance-in
using as keyword is faster, and I assume this has something to do with returning value always compared to prefix casting.
However I think you need to double check how you have implement GetUserBaseById(userId) method as I suspect it might not properly implemented for multithreaded environment.

Is it better to return null or an empty collection?

Suppose I have a method that returns an array or list or some other collection. If something goes wrong inside or when there is simply no data to return, what is better - to return null or to return array (list, etc.) that has length (count) equal to 0?
In fact is it important, or it is just a matter of developer's preferences?
It's better to return an empty collection. This way when someone calls the function like so:
foreach(var i in items)
{
}
it doesn't throw a null reference exception on them.
Technically, you could argue empty vs. null means, but in reality a lot of people (myself included at times) forget to be defensive and don't check to see if the object is null before using it. It's playing into what other people assume is going to happen, which means less bugs and less angry users.
Your iteration code will be a lot easier if you return empty collections instead of null.
However, it may be important to distinguish between an empty collection and no collection of data, so it depends on the semantic of the actual type.
If something "goes wrong" you should throw an exception. If there is no data to return, return an empty collection. Developers generally should not be surprised with a NullReferenceException when they ask for a list of items and there just happen to be none to return.
I could see this going either way. Ultimately an array or collection with have a larger footprint, but is "Safer" in the sense that if the result is being used in future foreach/iterations the result will skip over the code block and not end up with a null object exception.
Well, null and empty have two different meanings. An empty collection effectively means "nothing is here", and could be valid. How would you know if something went wrong based on an empty collection?
While it is safer for the calling method, that doesn't make it better than returning null. Good practice states you should check for null before doing operations on an object. It is cheap anyway.
If something truly went wrong, why cant you throw an exception?
It is developer's preference really.
Returning an empty list
Normally I'd return an empty list so that the receiver of the method's return object doesn't need to check for null and avoid any possible NullReferenceException.
So anyone that expects a list can iterate through the list even though the list is empty (that will be a very quick for-each loop).
Returning null
If you are in an environment where running out of memory is a large issue you could optimize to return null value instead. However that means that everyone that uses the method in question always need to check for null and doesn't solve the problem of possible memory leaks.
If something goes wrong then you shouldn't be returning anything, rather throwing an exception.
You need to agree a consistent approach for the project as to the meaning of NULL and {} and stick to it. Either you are going to use NULL or not, if you are everyone needs to know to check.
I like to think of NULL - not tried to or see if there is anything, there might be some but who knows.
Empty collection - tried to populate and as far as the system is concerned there are no items, which is quite a strong statement.
e.g. Wallet.Notes collection.
NULL - I haven't opened my wallet, so I don't know if I have any notes in it.
List={} - I've checked and I definitely don't have any notes cos I spent it all on beer.
Here is an article by Josh Bloch explaining the same. It's written in Java's context but it should apply to C# equally well.
Return zero-length arrays, not nulls
Although I'd say it's mostly a matter of developer's preference, to return an empty collection might be a better approach.
Let's say you have an object which contains a collection member.
public class Customer {
private IList<Order> _orders;
public Customer() {
_orders = new List<Order>();
}
public IList<Order> Orders {
get {
return _orders;
}
}
}
One generally will prefer to have this member as a readonly property so that its customer's orders don't get lost without any apparent reason. So, returning null is not an option. You would likely work better with an empty collection than a null reference. As such, instantiating the collection within the class constructor is a better approach.
And most importantly, when using DataBinding, for instance, you might get strange behaviour when returning null collection reference, as it will best work with an empty collection instead.
Another example, when iterating through a collection such as:
foreach (Order o in c.Orders) {
// Do something here...
}
This foreach loop will simply not get executed when the collection is empty, without you having to check whether it is a null reference first. It simplifies the code and minimizes its complexity.
This depends on the scenario you're wokring in.

Need help with NullReferenceException

DateTime mydt = new DateTime();
mydt = Convert.ToDateTime(com.Decrypt(Request.QueryString["Time"].ToString(), com.KeyCode.ToString()));
What am I doing wrong ? Its giving NullReferenceException.
Well, it's hard to say exactly what's going on because you've got lots of stuff going on in one statement.
As a simple aid to debugging, break that statement up into several separate ones - it'll make it a lot easier to find out what's going wrong. (Also note that your initial value of mydt is overwritten in the next statement anyway, so there's no point in it.)
Here's how I would rewrite your code:
// This already returns a string... you don't need to call ToString() on it
string encryptedTime = Request.QueryString["Time"];
// We don't know what "com" is here...
string key = com.KeyCode.ToString();
string decryptedTime = com.Decrypt(encryptedTime, key);
DateTime mydt = Convert.ToDateTime(decryptedTime);
(I'd also usually use DateTime.TryParseExact, but that's a different matter.)
A NullReferenceException occurs when you try to access a member of a null reference.
When you have a series of member accesses (using the '.' operator) and any reference is null, this will occur.
Any of these could be null:
com
Request.QueryString["Time"]
com.KeyCode
You can debug this by stopping on this line with a breakpoint (click on the line, press F9), and hover on each item in the above list. One of them is bound to be null.
Here's how you might redo your code in order to make it easier to read and debug issues like these:
DateTime mydt; // You don't need to initialize this with a new DateTime
if (com == null)
{
// Do something else, since nothing below this will work
}
var keyCode = com.KeyCode;
var time = Request.QueryString["Time"];
if (keyCode == null || time == null)
{
// Do something else, since nothing below this will work
}
mydt = Convert.ToDateTime(com.Decrypt(time.ToString(), keyCode.ToString()));
There are many possible null references here, but the most likely one is the Time query string variable. Make sure it exists.
Also, is your com variable set? And the com.KeyCode?
Several things can be null..
com, Request.QueryString["Time"], com.KeyCode
Set a breakpoint and find out ;)
One of your objects is null and when you try to access a property of a object that's null you receive a NullReferenceException.
Break out the code into multiple lines and test as either com, Request.QueryString["Time"] or com.KeyCode is null.
NullReferenceException come when a operation work on a object who have a null value or not have a valid value. you need to check that object have valid value or not null before making a operation on them.
if you parse it from anything that check that it is valid in some case if value not valid then he set the object as null in .net
As its name indicates, NullReferenceException is thrown because you are calling methods or properties on something that is null.
Therefore, you need to debug that expression to see which object is null at runtime, in the page you are testing.
We don't have enough info to answer your question directly. But...
There might not be a "Time" parameter in the query string?
Your variable com might be null? Was it properly instantiated?
As we don't see what page you are calling, we cannot tell.
So fire up visual studio and debug the expressions in there. Anyone of them could be null for any number of reasons.
NullReference essentially means that you are using a reference to an object when that object is null.

Should functions return null or an empty object?

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What is the best practice when returning data from functions. Is it better to return a Null or an empty object? And why should one do one over the other?
Consider this:
public UserEntity GetUserById(Guid userId)
{
//Imagine some code here to access database.....
//Check if data was returned and return a null if none found
if (!DataExists)
return null;
//Should I be doing this here instead?
//return new UserEntity();
else
return existingUserEntity;
}
Lets pretend that there would be valid cases in this program that there would be no user information in the database with that GUID. I Would imagine that it would not be appropriate to throw an exception in this case?? Also I am under the impression that exception handling can hurt performance.
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.
It depends on what makes the most sense for your case.
Does it make sense to return null, e.g. "no such user exists"?
Or does it make sense to create a default user? This makes the most sense when you can safely assume that if a user DOESN'T exist, the calling code intends for one to exist when they ask for it.
Or does it make sense to throw an exception (a la "FileNotFound") if the calling code is demanding a user with an invalid ID?
However - from a separation of concerns/SRP standpoint, the first two are more correct. And technically the first is the most correct (but only by a hair) - GetUserById should only be responsible for one thing - getting the user. Handling its own "user does not exist" case by returning something else could be a violation of SRP. Separating into a different check - bool DoesUserExist(id) would be appropriate if you do choose to throw an exception.
Based on extensive comments below: if this is an API-level design question, this method could be analogous to "OpenFile" or "ReadEntireFile". We are "opening" a user from some repository and hydrating the object from the resultant data. An exception could be appropriate in this case. It might not be, but it could be.
All approaches are acceptable - it just depends, based on the larger context of the API/application.
Personally, I use NULL. It makes clear that there is no data to return. But there are cases when a Null Object may be usefull.
If your return type is an array then return an empty array otherwise return null.
You should throw an exception (only) if a specific contract is broken.
In your specific example, asking for a UserEntity based on a known Id, it would depend on the fact if missing (deleted) users are an expected case. If so, then return null but if it is not an expected case then throw an exception.
Note that if the function was called UserEntity GetUserByName(string name) it would probably not throw but return null. In both cases returning an empty UserEntity would be unhelpful.
For strings, arrays and collections the situation is usually different. I remember some guideline form MS that methods should accept null as an 'empty' list but return collections of zero-length rather than null. The same for strings. Note that you can declare empty arrays: int[] arr = new int[0];
This is a business question, dependent on whether the existence of a user with a specific Guid Id is an expected normal use case for this function, or is it an anomaly that will prevent the application from successfully completing whatever function this method is providing the user object to...
If it's an "exception", in that the absence of a user with that Id will prevent the application from successfully completing whatever function it is doing, (Say we're creating an invoice for a customer we've shipped product to...), then this situation should throw an ArgumentException (or some other custom exception).
If a missing user is ok, (one of the potential normal outcomes of calling this function) then return a null....
EDIT: (to address comment from Adam in another answer)
If the application contains multiple business processes, one or more of which require a User in order to complete successfully, and one or more of which can complete successfully without a user, then the exception should be thrown further up the call stack, closer to where the business processes which require a User are calling this thread of execution. Methods between this method and that point (where the exception is being thrown) should just communicate that no user exists (null, boolean, whatever - this is an implementation detail).
But if all processes within the application require a user, I would still throw the exception in this method...
I personally would return null, because that is how I would expect the DAL/Repository layer to act.
If it doesn't exist, don't return anything that could be construed as successfully fetching an object, null works beautifully here.
The most important thing is to be consistant across your DAL/Repos Layer, that way you don't get confused on how to use it.
I tend to
return null if the object id doesn't exist when it's not known beforehand whether it should exist.
throw if the object id doesn't exist when it should exist.
I differentiate these two scenarios with these three types of methods.
First:
Boolean TryGetSomeObjectById(Int32 id, out SomeObject o)
{
if (InternalIdExists(id))
{
o = InternalGetSomeObject(id);
return true;
}
else
{
return false;
}
}
Second:
SomeObject FindSomeObjectById(Int32 id)
{
SomeObject o;
return TryGetObjectById(id, out o) ? o : null;
}
Third:
SomeObject GetSomeObjectById(Int32 id)
{
SomeObject o;
if (!TryGetObjectById(id, out o))
{
throw new SomeAppropriateException();
}
return o;
}
Yet another approach involves passing in a callback object or delegate that will operate on the value. If a value is not found, the callback is not called.
public void GetUserById(Guid id, UserCallback callback)
{
// Lookup user
if (userFound)
callback(userEntity); // or callback.Call(userEntity);
}
This works well when you want to avoid null checks all over your code, and when not finding a value isn't an error. You may also provide a callback for when no objects are found if you need any special processing.
public void GetUserById(Guid id, UserCallback callback, NotFoundCallback notFound)
{
// Lookup user
if (userFound)
callback(userEntity); // or callback.Call(userEntity);
else
notFound(); // or notFound.Call();
}
The same approach using a single object might look like:
public void GetUserById(Guid id, UserCallback callback)
{
// Lookup user
if (userFound)
callback.Found(userEntity);
else
callback.NotFound();
}
From a design perspective, I really like this approach, but has the disadvantage of making the call site bulkier in languages that don't readily support first class functions.
We use CSLA.NET, and it takes the view that a failed data fetch should return an "empty" object. This is actually quite annoying, as it demands the convention of checking whether obj.IsNew rathern than obj == null.
As a previous poster mentioned, null return values will cause code to fail straight away, reducing the likelihood of stealth problems caused by empty objects.
Personally, I think null is more elegant.
It's a very common case, and I'm surprised that people here seem surprised by it: on any web application, data is often fetched using a querystring parameter, which can obviously be mangled, so requiring that the developer handle incidences of "not found".
You could handle this by:
if (User.Exists(id)) {
this.User = User.Fetch(id);
} else {
Response.Redirect("~/notfound.aspx");
}
...but that's an extra call to the database every time, which may be an issue on high-traffic pages. Whereas:
this.User = User.Fetch(id);
if (this.User == null) {
Response.Redirect("~/notfound.aspx");
}
...requires only one call.
I prefer null, since it's compatible with the null-coalescing operator (??).
I'd say return null instead of an empty object.
But the specific instance that you have mentioned here,
you are searching for an user by user id, which is sort
of the key to that user, in that case I'd probably want
to to throw an exception if no user instance instance is
found.
This is the rule I generally follow:
If no result found on a find by primary key operation,
throw ObjectNotFoundException.
If no result found on a find by any other criteria,
return null.
If no result found on a find by a non-key criteria that may return a multiple objects
return an empty collection.
It will vary based on context, but I will generally return null if I'm looking for one particular object (as in your example) and return an empty collection if I'm looking for a set of objects but there are none.
If you've made a mistake in your code and returning null leads to null pointer exceptions, then the sooner you catch that the better. If you return an empty object, initial use of it may work, but you may get errors later.
The best in this case return "null" in a case there no a such user. Also make your method static.
Edit:
Usually methods like this are members of some "User" class and don't have an access to its instance members. In this case the method should be static, otherwise you must create an instance of "User" and then call GetUserById method which will return another "User" instance. Agree this is confusing. But if GetUserById method is member of some "DatabaseFactory" class - no problem to leave it as an instance member.
I personally return a default instance of the object. The reason is that I expect the method to return zero to many or zero to one (depending on the method's purpose). The only reason that it would be an error state of any kind, using this approach, is if the method returned no object(s) and was always expected to (in terms of a one to many or singular return).
As to the assumption that this is a business domain question - I just do not see it from that side of the equation. Normalization of return types is a valid application architecture question. At the very least, it is subject for standardization in coding practices. I doubt that there is a business user who is going to say "in scenario X, just give them a null".
In our Business Objects we have 2 main Get methods:
To keep things simple in the context or you question they would be:
// Returns null if user does not exist
public UserEntity GetUserById(Guid userId)
{
}
// Returns a New User if user does not exist
public UserEntity GetNewOrExistingUserById(Guid userId)
{
}
The first method is used when getting specific entities, the second method is used specifically when adding or editing entities on web pages.
This enables us to have the best of both worlds in the context where they are used.
I'm a french IT student, so excuse my poor english. In our classes we are being told that such a method should never return null, nor an empty object. The user of this method is supposed to check first that the object he is looking for exists before trying to get it.
Using Java, we are asked to add a assert exists(object) : "You shouldn't try to access an object that doesn't exist"; at the beginning of any method that could return null, to express the "precondition" (I don't know what is the word in english).
IMO this is really not easy to use but that's what I'm using, waiting for something better.
If the case of the user not being found comes up often enough, and you want to deal with that in various ways depending on circumstance (sometimes throwing an exception, sometimes substituting an empty user) you could also use something close to F#'s Option or Haskell's Maybe type, which explicitly seperates the 'no value' case from 'found something!'. The database access code could look like this:
public Option<UserEntity> GetUserById(Guid userId)
{
//Imagine some code here to access database.....
//Check if data was returned and return a null if none found
if (!DataExists)
return Option<UserEntity>.Nothing;
else
return Option.Just(existingUserEntity);
}
And be used like this:
Option<UserEntity> result = GetUserById(...);
if (result.IsNothing()) {
// deal with it
} else {
UserEntity value = result.GetValue();
}
Unfortunately, everybody seems to roll a type like this of their own.
I typically return null. It provides a quick and easy mechanism to detect if something screwed up without throwing exceptions and using tons of try/catch all over the place.
For collection types I would return an Empty Collection, for all other types I prefer using the NullObject patterns for returning an object that implements the same interface as that of the returning type. for details about the pattern check out link text
Using the NullObject pattern this would be :-
public UserEntity GetUserById(Guid userId)
{
//Imagine some code here to access database.....
//Check if data was returned and return a null if none found
if (!DataExists)
return new NullUserEntity(); //Should I be doing this here instead? return new UserEntity();
else
return existingUserEntity;
}
class NullUserEntity: IUserEntity { public string getFirstName(){ return ""; } ...}
To put what others have said in a pithier manner...
Exceptions are for Exceptional circumstances
If this method is pure data access layer, I would say that given some parameter that gets included in a select statement, it would expect that I may not find any rows from which to build an object, and therefore returning null would be acceptable as this is data access logic.
On the other hand, if I expected my parameter to reflect a primary key and I should only get one row back, if I got more than one back I would throw an exception. 0 is ok to return null, 2 is not.
Now, if I had some login code that checked against an LDAP provider then checked against a DB to get more details and I expected those should be in sync at all times, I might toss the exception then. As others said, it's business rules.
Now I'll say that is a general rule. There are times where you may want to break that. However, my experience and experiments with C# (lots of that) and Java(a bit of that) has taught me that it is much more expensive performance wise to deal with exceptions than to handle predictable issues via conditional logic. I'm talking to the tune of 2 or 3 orders of magnitude more expensive in some cases. So, if it's possible your code could end up in a loop, then I would advise returning null and testing for it.
Forgive my pseudo-php/code.
I think it really depends on the intended use of the result.
If you intend to edit/modify the return value and save it, then return an empty object. That way, you can use the same function to populate data on a new or existing object.
Say I have a function that takes a primary key and an array of data, fills the row with data, then saves the resulting record to the db. Since I'm intending to populate the object with my data either way, it can be a huge advantage to get an empty object back from the getter. That way, I can perform identical operations in either case. You use the result of the getter function no matter what.
Example:
function saveTheRow($prim_key, $data) {
$row = getRowByPrimKey($prim_key);
// Populate the data here
$row->save();
}
Here we can see that the same series of operations manipulates all records of this type.
However, if the ultimate intent of the return value is to read and do something with the data, then I would return null. This way, I can very quickly determine if there was no data returned and display the appropriate message to the user.
Usually, I'll catch exceptions in my function that retrieves the data (so I can log error messages, etc...) then return null straight from the catch. It generally doesn't matter to the end user what the problem is, so I find it best to encapsulate my error logging/processing directly in the function that gets the data. If you're maintaining a shared codebase in any large company this is especially beneficial because you can force proper error logging/handling on even the laziest programmer.
Example:
function displayData($row_id) {
// Logging of the error would happen in this function
$row = getRow($row_id);
if($row === null) {
// Handle the error here
}
// Do stuff here with data
}
function getRow($row_id) {
$row = null;
try{
if(!$db->connected()) {
throw excpetion("Couldn't Connect");
}
$result = $db->query($some_query_using_row_id);
if(count($result) == 0 ) {
throw new exception("Couldn't find a record!");
}
$row = $db->nextRow();
} catch (db_exception) {
//Log db conn error, alert admin, etc...
return null; // This way I know that null means an error occurred
}
return $row;
}
That's my general rule. It's worked well so far.
Interesting question and I think there is no "right" answer, since it always depends on the responsibility of your code. Does your method know if no found data is a problem or not? In most cases the answer is "no" and that's why returning null and letting the caller handling he situation is perfect.
Maybe a good approach to distinguish throwing methods from null-returning methods is to find a convention in your team: Methods that say they "get" something should throw an exception if there is nothing to get. Methods that may return null could be named differently, perhaps "Find..." instead.
If the object returned is something that can be iterated over, I would return an empty object, so that I don't have to test for null first.
Example:
bool IsAdministrator(User user)
{
var groupsOfUser = GetGroupsOfUser(user);
// This foreach would cause a run time exception if groupsOfUser is null.
foreach (var groupOfUser in groupsOfUser)
{
if (groupOfUser.Name == "Administrators")
{
return true;
}
}
return false;
}
I like not to return null from any method, but to use Option functional type instead. Methods that can return no result return an empty Option, rather than null.
Also, such methods that can return no result should indicate that through their name. I normally put Try or TryGet or TryFind at the beginning of the method's name to indicate that it may return an empty result (e.g. TryFindCustomer, TryLoadFile, etc.).
That lets the caller apply different techniques, like collection pipelining (see Martin Fowler's Collection Pipeline) on the result.
Here is another example where returning Option instead of null is used to reduce code complexity: How to Reduce Cyclomatic Complexity: Option Functional Type
More meat to grind: let's say my DAL returns a NULL for GetPersonByID as advised by some. What should my (rather thin) BLL do if it receives a NULL? Pass that NULL on up and let the end consumer worry about it (in this case, an ASP.Net page)? How about having the BLL throw an exception?
The BLL may be being used by ASP.Net and Win App, or another class library - I think it is unfair to expect the end consumer to intrinsically "know" that the method GetPersonByID returns a null (unless null types are used, I guess).
My take (for what it's worth) is that my DAL returns NULL if nothing is found. FOR SOME OBJECTS, that's ok - it could be a 0:many list of things, so not having any things is fine (e.g. a list of favourite books). In this case, my BLL returns an empty list. For most single entity things (e.g. user, account, invoice) if I don't have one, then that's definitely a problem and a throw a costly exception. However, seeing as retrieving a user by a unique identifier that's been previously given by the application should always return a user, the exception is a "proper" exception, as in it's exceptional. The end consumer of the BLL (ASP.Net, f'rinstance) only ever expects things to be hunky-dory, so an Unhandled Exception Handler will be used instead of wrapping every single call to GetPersonByID in a try - catch block.
If there is a glaring problem in my approach, please let me know as I am always keen to learn. As other posters have said, exceptions are costly things, and the "checking first" approach is good, but exceptions should be just that - exceptional.
I'm enjoying this post, lot's of good suggestions for "it depends" scenarios :-)
I think functions should not return null, for the health of your code-base. I can think of a few reasons:
There will be a large quantity of guard clauses treating null reference if (f() != null).
What is null, is it an accepted answer or a problem? Is null a valid state for a specific object? (imagine that you are a client for the code). I mean all reference types can be null, but should they?
Having null hanging around will almost always give a few unexpected NullRef exceptions from time to time as your code-base grows.
There are some solutions, tester-doer pattern or implementing the option type from functional programming.
I am perplexed at the number of answers (all over the web) that say you need two methods: an "IsItThere()" method and a "GetItForMe()" method and so this leads to a race condition. What is wrong with a function that returns null, assigning it to a variable, and checking the variable for Null all in one test? My former C code was peppered with
if ( NULL != (variable = function(arguments...)) ) {
So you get the value (or null) in a variable, and the result all at once. Has this idiom been forgotten? Why?
I agree with most posts here, which tend towards null.
My reasoning is that generating an empty object with non-nullable properties may cause bugs. For example, an entity with an int ID property would have an initial value of ID = 0, which is an entirely valid value. Should that object, under some circumstance, get saved to database, it would be a bad thing.
For anything with an iterator I would always use the empty collection. Something like
foreach (var eachValue in collection ?? new List<Type>(0))
is code smell in my opinion. Collection properties shouldn't be null, ever.
An edge case is String. Many people say, String.IsNullOrEmpty isn't really necessary, but you cannot always distinguish between an empty string and null. Furthermore, some database systems (Oracle) won't distinguish between them at all ('' gets stored as DBNULL), so you're forced to handle them equally. The reason for that is, most string values either come from user input or from external systems, while neither textboxes nor most exchange formats have different representations for '' and null. So even if the user wants to remove a value, he cannot do anything more than clearing the input control. Also the distinction of nullable and non-nullable nvarchar database fields is more than questionable, if your DBMS is not oracle - a mandatory field that allows '' is weird, your UI would never allow this, so your constraints do not map.
So the answer here, in my opinion is, handle them equally, always.
Concerning your question regarding exceptions and performance:
If you throw an exception which you cannot handle completely in your program logic, you have to abort, at some point, whatever your program is doing, and ask the user to redo whatever he just did. In that case, the performance penalty of a catch is really the least of your worries - having to ask the user is the elephant in the room (which means re-rendering the whole UI, or sending some HTML through the internet). So if you don't follow the anti-pattern of "Program Flow with Exceptions", don't bother, just throw one if it makes sense. Even in borderline cases, such as "Validation Exception", performance is really not an issue, since you have to ask the user again, in any case.
An Asynchronous TryGet Pattern:
For synchronous methods, I believe #Johann Gerell's answer is the pattern to use in all cases.
However the TryGet pattern with the out parameter does not work with Async methods.
With C# 7's Tuple Literals you can now do this:
async Task<(bool success, SomeObject o)> TryGetSomeObjectByIdAsync(Int32 id)
{
if (InternalIdExists(id))
{
o = await InternalGetSomeObjectAsync(id);
return (true, o);
}
else
{
return (false, default(SomeObject));
}
}

Categories