Is it acceptable to use exceptions instead of verbose null-checks? - c#

I recenly encountered this problem in a project: There's a chain of nested objects, e.g.: class A contains an instance variable of class B, which in turns has an instance variable of class C, ..., until we have a node in the tree of class Z.
----- ----- ----- ----- -----
| A | ---> | B | ---> | C | ---> | D | ---> ... ---> | Z |
----- ----- ----- ----- -----
Each class provides getters and setters for its members. The parent A instance is created by an XML parser, and it is legal for any object in the chain to be null.
Now imagine that at a certain point in the application, we have a reference to an A instance, and only if it contains a Z object, we must invoke a method on it. Using regular checks, we get this code:
A parentObject;
if(parentObject.getB() != null &&
parentObject.getB().getC() != null &&
parentObject.getB().getC().getD() != null &&
parentObject.getB().getC().getD().getE() != null &&
...
parentObject.getB().getC().getD().getE().get...getZ() != null){
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
}
I know that exceptions should not be used for ordinary control flow, but instead of the previous code, I have seen some programmers doing this:
try {
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
} catch (NullPointerException e){}
The problem with this code is that it may be confuse when maintaining it, since it doesn't show clearly which objects are allowed to be null. But on the other hand is much more concise and less "telescopic".
Is it an acceptable to do this to save development time?
How could the API be redesigned to avoid this problem?
The only thing I can think of to avoid the long null checking is to provide void instances of the nested objects and providing isValid methods for each one of them, but wouldn't this create a lot of innecesary objects in memory?
(I've used Java code, but the same question can apply to C# properties)
Thanks.

It is bad design if parentObject needs to know that A contains a B which contains a C wich contains.... That way, everything is coupled to everything. You should have a look at the law of demeter: http://en.wikipedia.org/wiki/Law_Of_Demeter
parentObject should only call methods on its instance variable B. So, B should provide a method that allows for the decision, e.g.
public class A {
private B myB;
//...
public boolean isItValidToDoSomething(){
if(myB!=null){
return myB.isItValidToDoSomething();
}else{
return false;
}
}
}
Eventually, at the level of Z, the method has to return true.
Imho, saving development time is never a reason for tolerating problems in the design. Sooner or later these problems will steal you more time than it would have taken to fix the problems in the first place

It's bad practice to use Exceptions here.
There's a hint in the name: Exceptions are for exceptional circumstances (i.e. unexpected) . If nulls are expected values, then encountering them is not exceptional.
Instead, I'd have a look at the class hierarchy and try to understand why such deep access chaining needs to happen. This seems like a big design issue, you shouldn't normally expect the caller to construct calls using deep knowledge of the structure of objects hidden within class A.
Questions you could ask:
Why does the caller need to doSomething() with the Z object anyway? Why not put the doSomething() on class A? This could propagate doSomething() down the chain if needed and if the relevant field was not null....
What does a null mean if it exists in this chain? The meaning of a null will suggest what business logic should be employed to handle it.... which could be different at each level.
Overall, I suspect the right answer is to put doSomething() on each level of the heirarchy and have the implementation something like:
class A {
...
public void doSomething() {
B b=getB();
if (b!=null) {
b.doSomething();
} else {
// do default action in case of null B value
}
}
}
If you do this, then the API user only has to call a.doSomething(), and you have the added bonus that you can specify different default actions for a null value at each level.

Personally I like to avoid this problem altogether by using an option type. By adjusting the value returned from these methods/properties to be Option<T> rather than T the caller can choose how they wish to handle the case of no value.
An option type can either have a contained value or not (but the option itself can never be null), but the caller cannot simply pass it on without unwrapping the value so it forces the caller to deal with the fact there may be no value.
E.g. in C#:
class A {
Option<B> B { get { return this.optB; } }
}
class B {
Option<C> C { get { return this.optC; } }
}
// and so on
If the caller wants to throw, they merely retrieve the value without explicitly checking to see if there is one:
A a = GetOne();
D d = a.Value.B.Value.C.Value.D.Value; // Value() will throw if there is no value
If the caller wants to just default if any step doesn't have a value, they can perform mapping/binding/projection:
A a = GetOne();
D d = a.Convert(a => a.B) // gives the value or empty Option<B>
.Convert(b => b.C) // gives value or empty Option<C>
.Convert(c => c.D) // gives value or empty Option<D>
.ValueOrDefault(new D("No value")); // get a default if anything was empty
If the caller wants to default at each stage, they can:
A a = GetOne();
D d = a.ValueOrDefault(defaultA)
.B.ValueOrDefault(defaultB)
.C.ValueOrDefault(defaultC)
.D.ValueOrDefault(defaultD);
Option is not currently part of C# but I imagine one day will be. You can get an implementation by referencing the F# libraries or you may be able to find an implementation on the web. If you'd like mine, let me know and I'll send it to you.

Well, it depends on exactly what you're doing in the catch. In the above case, it appears that you want to call doSomething() if it's available, but if it isn't you don't care. In this case I would say that trapping the specific exception you're after is just as acceptable as a verbose check to ensure you won't throw one to begin with. There are many "null-safe" methods and extensions that use try-catch in a very similar manner to what you propose; "ValueOrDefault"-type methods are very powerful wrappers for exactly what's been done with the try-catch, for exactly the reason try-catch was used.
Try/catch is, by definition, a program flow control statement. Therefore, it is expected to be used to "control ordinary program flow"; I think the distinction you are trying to make is that it should not be used to control the "happy path" of normal error-free logic flow. Even then I might disagree; there are methods in the .NET Framework and in third-party libraries that either return the desired result or throw an exception. An "exception" is not an "error" until you cannot continue because of it; if there's something else you can try or some default case the situation can boil down to, it can be considered "normal" to receive an exception. So, catch-handle-continue is a perfectly valid use of try-catch, and many uses of exception throwing in the Framework expect you to handle them robustly.
What you want to avoid is using try/catch as a "goto", by throwing exceptions that aren't really exceptions in order to "jump" to the catch statement once some condition is satisfied. This is definitely a hack, and thus bad programming.

The problem with the "catch an exception" approach is that it seems a bit heavy-handed. The exception stack trace should show you where it failed since your method names make it quite clear where you are in the hierarchy but it is not a good way of going about it. Plus how would you recover from the exception and carry on to a good state of your code?
If you must keep this very deep hierarchy then you could use static instances of each object which defines an "empty" state. The best example I can think of which does this is the C# string class which has a static string.Empty field. Then each call of getB(), getC() ... getZ() would return either a real value or the "empty" state, allowing you to chain the method calls.
By making the "empty" state instances static there would only be one of each type in your system. But you would need to consider what an "empty" state looks like for each type in your hierarchy and make sure it doesn't affect any other part of your application inadvertently.

In Python, they encourage the style of "easier to ask forgiveness than permission", which could be applied here to say that it's better to just optimistically try to get to Z without safety checking, and let the exception handler fix a miss. That's easier to code, and it's more performant if the call of Z not being in the call chain is less likely than the case that it will be.
Aside from violating a bunch of OOP good design principles and exposing deeply nested private members, this code also seems vaguely dynamic in nature. That is, you want to call method X but only if X exists on the object, and you want that logic to apply to all objects in a hierarchy of unknown length. And you can't change the design because this is what your XML translation gives you.
Can you change languages then? Statically-typed C# may not be the best choice for what you're doing here. Maybe using Iron Python or some other language that's a little looser on typing will let you more easily manipulate your DOM. Once you've got the data in a stable state, you can pass that off to C# for the rest.

Using exceptions seem a poor fit here. What if one of the getters contained non-trivial logic, and threw a NullPointerException? Your code would swallow that exception without intending to. On a related note, your code samples exhibit different behaviour if parentObject is null.
Also, there really is no need to "telescope":
public Z findZ(A a) {
if (a == null) return null;
B b = a.getB();
if (b == null) return null;
C c = b.getC();
if (c == null) return null;
D d = c.getD();
if (d == null) return null;
return d.getZ();
}

I think you could provide static isValid methods on each class, for example for class A that would be:
public class A {
...
public static boolean isValid (A obj) {
return obj != null && B.isValid(obj.getB());
}
...
}
And so on. Then you would have:
A parentObject;
if (A.isValid(parentObject)) {
// whatever
}
However, although I won't get into you business I must say that such a method chaining does not say anything good about the design; maybe it's a sign of need for refactoring.

I agree with the other answers that this should not need to be done, but if you must here is an option:
You could create an enumerator method once such as:
public IEnumerable<type> GetSubProperties(ClassA A)
{
yield return A;
yield return A.B;
yield return A.B.C;
...
yield return A.B.C...Z;
}
And then use it like:
var subProperties = GetSubProperties(parentObject);
if(SubProperties.All(p => p != null))
{
SubProperties.Last().DoSomething();
}
The enumerator will be lazily evaluated leading to no exceptions.

Related

void vs. object returning null

Since void signature is used to denote that a method does not return anything, such kind of methods, I write it the following way:
private void MyMethod()
{
// Body of the method.
}
However, in many places I have seen methods that are not intended to return anything, written in following way:
private object MyMethod()
{
// Body of the method
return null;
}
From my point of view, both code pieces do the same. So, which can be the purpose of using this second one? Which is the difference between them? And is any of them preferred over the other?
The second one written as is, with a single return is generally useless, it'll slow down the performance slightly and makes the API harder to consume. There are however slight variations where it may be useful such as:
There are multiple return points, and this is the final one indicating a lack of an object. For example you might be returning an instance of an object normally, but for some reason you don't have one this time around. (Example 1)
If the method were marked differently, say public virtual then the default implementation or an overridden one may not return a value, but others might. (Example 2)
Example 1:
public object MyMethod()
{
if(myObj != null)
return myObj.Result();
return null;
}
Example 2:
// Derived Class
protected override object MyMethod()
{
// We don't need a result from here so we don't have an implementation of
// anything, but the base implementation doesn't make sense. This however
// could be breaking SOLID principles.
return null;
}
// Base Class
protected virtual object MyMethod()
{
return new MyObj();
}
perhaps the second can be used to call an exception treatment
With the second one, the caller can test for nullness which is a useful indication of success or failure, if for some reason, it's not desirable to throw an exception. With the first one no such facility is available.
The second one is a bad practice. We are unnecessary telling the compiler to check for the return type. Maybe it is done for future changes.
For the second one, if there is no other return value in the method body, I would say it is useless. As long as you guarantee the method won't return any value, please use the first one.
second method itself returning something in your case its null. i dont feel it as non value returning method. if method is not returning better to practice with void
The only good practice would be returning a bool value every time, to confirm if the method has received the call and arguments successfully OR if the method did successfully execute the logic inside.
Returning a NULL is useless and misleading...
Second is misleading. Someone who uses your class would expect to get something after executing this method. You should avoid writing such methods if they do not intend to return meaningful values under any circumstances.
Even if you overidding class which returns something meaningful you should consider using NullObject design pattern so that you do not broke existing APIs and follow LSP. Returning null creates redundancies with extra null checking logic and is counterintuitive.

Throwing exceptions for legal states in code

The Exception is a convenient container, that is tempting to use for various purposes. But is it OK to use it for handling legal states in your code?
My example: I have a geometric function that finds the closest object within a search radius:
public IPoint FindNearest(IPoint origin, double searchRadius)
{
}
My idea was that I could throw an exception, when the search doesn't find a hit. But is this a good idea? Alternatively, I could return Null (which I don't like), or return a result object instead of a Point.
Exception, in general, represents an invalid or "exceptional" scenario. In your case, if not finding a hit is an exceptional scenario and it should always be found in usual cases then you can throw exception.
You should always try to avoid throwing exception because of its heavy nature. If caller code is calling this method frequently and your method is in result throwing lot of exceptions, it will make your program slow
Best practice is to use exception only if you can not handle the error in a functial way. In this case not finding a location and returning null is best, because your calling function can handle the null in a functional way. Besides the clean code, throwing and handling exceptions is realy bad for performance, so use them only as last resort.
You could do something like
public bool TryFindNearest(IPoint origin, double searchRadius, out IPoint result)
{
// your logic here, return true if you find a point. Otherwise return false.
}
Then your calling code can do something like:
IPoint nearestPoint;
If (TryFindNearest(origin, searchRadius, out nearestPoint))
{
// do your stuff.
}
Exceptions should be used in invalid scenarios not to control program flow.
Usually in this situation throwing exceptions isn't a good idea, they are expensive and semantically mean something else entirely.
You could return null and do a null check, or I occasionally find that using the Special Case pattern works out nicely and makes for readable code if you give the class/interface a sensible name.
In this instance, you'd return either an implementing class or derived interface called something like:
public class NoHitOnRadius : IPoint {}
And return that from the call when you get no hits. Then the calling code checks the return type:
var p = FindNearest(...);
if (p is NoHitOnRadius)
{
// Do something.
}
Although in this specific situation I'd likely go with the TryFindNearest semantics (to keep commonality with the likes of TryParse etc) that RobH suggests.

Checking for invalid values in methods

I am trying to find the right way to write code regarding checking for the invalid values. Invalid value, in my case, would be null. The thing with other questions in SO is that they fall under specific circumstances and I am interested in a more general solutions.
I have a code like this:
public class SomeClass
{
private readonly object m_internallyUsedObject;
private ThirdPartyObject m_user; // Third party object.
public SomeClass(object internallyUsedObject)
{
m_internallyUsedObject = internallyUsedObject; // We just want to ensure that the object will remain the same throught the life time of SomeClass object.
m_user = new ThirdPartyObject(); // This object is not yet needed here.
}
public void DoSomething()
{
m_user.DoSomethingElse(m_internallyUsedObject); // Now we're using it and we are not sure whether null value is tolerated.
}
}
Since we take the internallyUsedObject in constructor, we probably know the semantics of this object and how it should be used. On the other hand, we just relay this object to a third party object during calls.
Our SomeClass object will work just fine regardless of whether the value is null or not.
Now, the problem is that we do not know whether null will always work for the ThirdPartyObject - it might work in one version (in which case it's OK to omit null check) and do not work in another.
One could say that we should not care for checking for null if our class can handle it. But when I write the code documentation, I would like to tell the user the behavior and expectations of our own class.
As I mentioned above, this simple check might not be useful or even invalid in particular third party object's versions:
if (internallyUsedObject == null)
{
throw new ArgumentNullException("internallyUsedObject");
}
Is it valid according to the OOP to take the internallyUsedObject from the code above inside the constructor when we are not going to use it directly? Doesn't it violate the "fail fast" principle, since it might appear that we are just deferring the problem to the later stage of the object's life time?
As a rule I've tended to use the method you've described in the second code block, but in combination with sensible groupings of checks. By this I mean that certain checks for particular methods should be performed and actions taken before an logic is performed e.g.
public void MyMethod(MyObject input) {
// 1. perhaps security checks, if an in method security is required
if(security.AccessLevel < requiredLevel)
throw new CustomSecurityException("Insufficent Access");
// 2. data checks
if(input.Property == null)
throw new ArgumentNullException("Input didn't contain the value I wanted");
if(input.Property2 < someImportantLevel)
throw new CustomBLException("Input didn't meet required level for something");
// 3. perform BL
// ...do whatever
}
It's probably not ideal and often things like method attributes could be used for the security side of things but in quite a few of our apps this has seemed like a sensible grouping of checks. You know that all the checks are done up front rather than lengthy blocks like this:
if(input != null) {
//do logic
} else {
throw new Exception();
}
Where the checks could be hidden or nested and harder to locate.

The usefulness of AS operator in C# [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Direct casting vs 'as' operator?
Where could this operator be useful? Instead of writing this:
Asset a = new Asset();
Stock s = a as Stock; // s is null; no exception thrown
if (s != null) Console.WriteLine (s.SharesOwned);
You'd better write something that throws. I saw tons of
(s != null)
in production code and it really becomes ugly. Exceptions are more descriptive and natural in that way. Even conceptually: how can you get no asset if it is not a stock? It should an exception if it is not a stock.
You often have the case where you don’t want an exception to be thrown because, well, the situation isn’t exceptional. You have a frob object which you know can be a Foo, but could also be a Bar. So you want to perform some action only if it’s a Foo.
You try to avoid these situations in designs, and use virtual methods instead. But sometimes there’s just no good way around that.
So rather than taking the roundabout way,
if (frob is Foo) {
((Foo) frob).Frobnicate();
}
you do it directly:
var asFoo = frob as Foo;
if (asFoo != null) {
asFoo.Frobnicate();
}
If nothing else, this is at least more efficient since you only need to test for type equality once (inside the as cast) instead of twice (in the is and in the cast).
As a concrete example, this is very useful when you want to clear all the input boxes in a form. You could use the following code:
foreach (Control c in this.Controls) {
var tb = c As TextBox;
if (tb != null)
tb.Clear();
}
Using an exception here would make no sense.
You'd better write something that throws
Not necessarily. Users don't like seeing things throwing. You should write code that works. And if it doesn't you'd better handle it appropriately by apologizing to the user. The as operator can be useful in situations where for example you would attempt a cast and if this cast doesn't work assign a default value to the variable so that the code continues to work with this default value. It would really depend on the context.
as does an is and if the is returns false assigns null.
sounds like a song but it's the answer and I use it a lot, like in the FindControl methods of ASP.NET:
Button myButton = e.item.FindControl("myControlId") as Button;
this kind of assignment does not crash or throw simply assigns null if FindControl finds something different than a Button. I like this so much....
If Asset is inherited from Stock, then this should be fine. That's the only sort of case where I've seen that work, although you could prolly also use it in the case of interfaces.
Yes, the as operator is useful, and yes, it can be misused.
If you are sure that some variable x is of type T, you should use a regular cast.
T y = (T)x;
If both T1 and T2 are valid types for variable x, you cau use as to check the type and perform the cast in one operation.
What are your requirements?
If the asset is a stock print the number of shares owned.
The as operator is very useful in that case but you will have to check stock != null. That is implied by the requirement.
Print the number of shares owned of a stock. It is an error if another asset is supplied.
Then you should write code that throws an exception.
Exceptions are not designed for flow control, they are, by definition, exceptions to the normal train of events. If it's acceptable for the conversion to fail, use as. If, rather, not being able to cast "a" as a Stock should never happen, you can use simple s=(Stock)a; which will throw it's own exception. You have no control of the exception at this point, though.
The following lets the developer handle the exceptional case much cleaner:
Asset a= new Asset();
Stock s= a as Stock();
if(s == null) {
// Safely exit from call if possible, maybe make calls to logging mechanism or
// other ways of determining why an exception occurred. Also, could throw custom
// Exception if needed with much more detailed info.
} else {
// Continue normal flow
}
You could do:
Asset a= new Asset();
try
{
Stock s= (Stock);
// Continue normal flow
}
catch (InvalidCastException exc)
{
// Safely exit from call if possible, maybe make calls to logging mechanism or
// other ways of determining why an exception occurred. Also, could throw custom
// Exception if needed with much more detailed info.
}
However, that is using the exception as flow control and is costly and bad design.
It depends on your Error Handling policy. I work on code base where we always use casting than using as operator. However, there are some cases where AS operator is very much useful and faster than exception.
For example,
In following case what do you What do you prefer?
public bool Process(int choice)
{
try
{
Thing thing = GetRequiredThing(choice);
SubThing subThing = (SubThing)thing;
}
catch (InvalidCastException ex)
{
// report ex.
return false;
}
}
or
public bool Process(int choice)
{
Thing thing = GetRequiredThing(choice);
SubThing subThing = thing as SubThing;
if (subThing == null)
{
//report error;
return false;
}
}
If is not necessary that you should always use as operator. Take your call.

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