Checking for null in an object hierarchy - c#

I have a large C# (3.0) object structure originating from a deserialized XML document. I need to know whether a variable deep in the hierarchy is null. The way I do this now is to check every parent object on the way down for null, but this leads to a long repetition of if statements.
I am trying to avoid expensive try-catch blocks.
Is there a smarter way to do this?
edit:
For example after a deserialization of an XML application form into an object hierarchy structure there could potentially be a salary value under
applicationForm.employeeInfo.workingConditions.salary
but to find out safely I have to write something like
if (applicationForm.employeeInfo != null)
if (applicationForm.employeeInfo.workingConditions != null)
if (applicationForm.employeeInfo.workingConditions.salary != null)
because simply using the latter if-statement will of course fail if one of the parent objects is null.
So I am looking for any smarter way to handle this situation.

You've run into the classic situation where each step in A.B.C.D may yield null. Though this is a common scenario, surprisingly there's no common pattern for solving it, other then using a large if-statement with lots of or's (||).
If each step can return a different class, then there's a rarely used pattern that you can apply: Use a generalized generic extension method with method chaining.
A generalized extension method is not a fixed term but I use it here for emphasizing that the ext. method is applicable to almost all types of objects, hence generalized. According to Bill Wagner in Effective C#, this is bad design. But in some remote cases, like yours, you can use it as long as you know what you're doing and why.
The trick is simple: define a generic extension method and generalize it for all classes that have a default constructor. If the test fails (object is null), the method returns a new object of the same type. Otherwise, it will return the unchanged object itself.
Why is this a good approach for your scenario? Because you don't need to change any existing classes, because it's understandable and promotes readable code, because it keeps type safety (compile time errors instead of runtime errors) and it's simply more concise compared to other approaches.
// extension method:
public static class SomeExtentionMethods
{
public static T SelfOrDefault<T>(this T elem)
where T : class, new() /* must be class, must have ctor */
{
return elem ?? new T(); /* return self or new instance of T if null */
}
}
// your code now becomes very easily readable:
Obj someObj = getYourObjectFromDeserializing();
// this is it applied to your code:
var mySalary = applicationForm.SelfOrDefault().
employeeInfo.SelfOrDefault().
workingConditions.SelfOrDefault().
salary;
// now test with one if-statement:
if(mySalary.IsEmpty())
// something in the chain was empty
else
// all's well that ends well :)
The beauty of this approach is that it works with all types of classes (provided they have a ctor), including collections and arrays. If any step is an index step, it will still work (depending on the collection, an invalid index can return null, default or raise an exception):
var x =
someObj.SelfOrDefault()
.Collection.SelfOrDefault()
.Items[1].SelfOrDefault()
.Mother.SelfOrDefault()
.Father.SelfOrDefault();
Update: expanded a bit and added a more elaborate example
Update: renamed NotNull, which implies boolean, to SelfOrDefault, which follows LINQ's naming convention (FirstOrDefault etc) and implies what it does.
Update: rewritten and reorganized, made code more applicable, hoping to make it more understandable overall :)

Firstly, if you're repeating the logic in more than one place, encapsulate it in a method.
Secondly, you don't need lots of if statements, you just need one with a lot of OR conditions:
if(parent==null ||
parent.Child == null ||
parent.Child.GrandChild == null ...
Thirdly, "avoiding expensive try/catch blocks" may be a premature optimization, depending on your scenario. Have you actually tried this and profiled it, and is it really causing a large overhead?

You can nest ternary operators. Still a pain, but not as bad as nested ifs.
string salary = (applicationForm.employeeInfo == null) ? null :
(applicationForm.employeeInfo.workingConditions == null) ? null :
applicationForm.employeeInfo.workingConditions.salary;
If you just want to know whether or not it is null:
bool hasSalary = (applicationForm.employeeInfo == null) ? false :
(applicationForm.employeeInfo.workingConditions == null) ? false :
(applicationForm.employeeInfo.workingConditions.salary != null);

Here's my simple solution:
if (applicationForm?.employeeInfo?.workingConditions?.salary != null)
Here any of these objects (applicationForm, employeeInfo, workingConditions, salary) can be null and it will resolve without error.

can't you iterate?
for (SomeObject obj = someInstance; obj != null; obj = obj.Parent) {
//do something
}

Use reflection.
Create a helper method that takes a parent object and a hierarchical dot notated string for your property names. Then use PropertyInfo and use recursion to go down one property at a time each time checking for null and returning null if so, else continuing down the hierarchy.

Since you didn't provide all too many details I had to fill in alot of the blanks. Here is a psuo-codeish example of how you might accomplish this via recursion
public bool doesHierarchyContainANull(MyObject ParentObject)
{
if (ParentObject.getMemberToCheckForNull() == null)
return true;
else if (ParentObject.isLastInHierarchy())
return false;
return doesHierarchyContainANull(ParentObject.getNextInHierarchy());
}

I liked the answer by Pontus Bremdahl, but added some more detail for my uses.
Code:
/// <summary>
/// Get a member in an object hierarchy that might contain null references.
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source">Base object to get member from.</param>
/// <param name="getResult">Member path.</param>
/// <param name="defaultResult">Returned object if object hierarchy is null.</param>
/// <returns>Default of requested member type.</returns>
public TResult SafeGet<TSource, TResult>(TSource source, Func<TSource, TResult> getResult, TResult defaultResult)
{
// Use EqualityComparer because TSource could by a primitive type.
if (EqualityComparer<TSource>.Default.Equals(source, default(TSource)))
return defaultResult;
try
{
return getResult(source);
}
catch
{
return defaultResult;
}
}
/// <summary>
/// Get a member in an object hierarchy that might contain null references.
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source">Base object to get member from.</param>
/// <param name="getResult">Member path.</param>
/// <returns>Default of requested member type.</returns>
public TResult SafeGet<TSource, TResult>(TSource source, Func<TSource, TResult> getResult)
{
// Use EqualityComparer because TSource could by a primitive type.
if (EqualityComparer<TSource>.Default.Equals(source, default(TSource)))
return default(TResult);
try
{
return getResult(source);
}
catch
{
return default(TResult);
}
}
Usage:
// Only authenticated users can run this code
if (!HttpContext.Current.SafeGet(s => s.User.Identity.IsAuthenticated))
return;
// Get count limit from app.config
var countLimit = int.Parse(ConfigurationManager.AppSettings.SafeGet(
s => s.Get("countLimit"),
"100" // Default 100 if no value is present
));
// Is int 6 a class? Always no, but just to show primitive type usage.
var is6AClass = 6.SafeGet(i => i.GetType().IsClass);
Update
CSharp version 6 now has this built into it.
https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#null-conditional-operators
Null-conditional operators
Sometimes code tends to drown a bit in null-checking. The null-conditional operator lets you access members and elements only when the receiver is not-null, providing a null result otherwise:
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0]; // null if customers is null
The null-conditional operator is conveniently used together with the null coalescing operator ??:
int length = customers?.Length ?? 0; // 0 if customers is null
The null-conditional operator exhibits short-circuiting behavior, where an immediately following chain of member accesses, element accesses and invocations will only be executed if the original receiver was not null:
int? first = customers?[0].Orders.Count();
This example is essentially equivalent to:
int? first = (customers != null) ? customers[0].Orders.Count() : null;
Except that customers is only evaluated once. None of the member accesses, element accesses and invocations immediately following the ? are executed unless customers has a non-null value.
Of course null-conditional operators can themselves be chained, in case there is a need to check for null more than once in a chain:
int? first = customers?[0].Orders?.Count();
Note that an invocation (a parenthesized argument list) cannot immediately follow the ? operator – that would lead to too many syntactic ambiguities. Thus, the straightforward way of calling a delegate only if it’s there does not work. However, you can do it via the Invoke method on the delegate:
if (predicate?.Invoke(e) ?? false) { … }
We expect that a very common use of this pattern will be for triggering events:
PropertyChanged?.Invoke(this, args);
This is an easy and thread-safe way to check for null before you trigger an event. The reason it’s thread-safe is that the feature evaluates the left-hand side only once, and keeps it in a temporary variable.

CheckForNull(MyType element)
{
if(element.ChildElement != null)
{
CheckForNull(element.ChildElement);
}
else
{
Console.WriteLine("Null Found");
}
}

You need a recursive function to iterate through the structure and check each node and its children for null. I was working on a sample but IE crashed (typical!!). Will post one later.
Sample
You could do something as simple (assuming you only ever want to just check if the structure is valid) as this:
public void ValidateStructure()
{
Node root = // get the root node
try
{
ValidateChildren(root);
Console.WriteLine("All nodes are valid");
}
catch (NullReferenceException)
{
Console.WriteLine("Structure contained a null node.");
}
}
public void ValidateChildren(Node parent)
{
// an NullReferenceException would be raised here since parent would be null
foreach (var child in parent.Children)
{
ValidateChildren(child);
}
}

My solution would be something like:
public static TResult SafeGet<TSource, TResult>(this TSource source, Func<TSource, TResult> getResult) {
if (source == null)
return default(TResult);
try {
return getResult(source);
}
catch {
return default(TResult);
}
}
Usage:
Test myTestObject = null;
var myStringOrNull = myTestObject.SafeGet(x => x.test.test.test.mySring);

Use the Null monad. It can be in the same file or a different file so long as you using it.
public static class NullMonad {
public static TResult SelectMany<TIn, TOut, TResult>(this TIn #in, Func<TIn, TOut> remainder, Func<TIn, TOut, TResult> resultSelector)
where TIn : class
where TOut : class
where TResult : class {
var #out = #in != null ? remainder(#in) : null;
return #out != null ? resultSelector(#in, #out) : null;
}
}
Then you can use LINQ:
var salary = from form in applicationForm
from info in form.employeeInfo
from cond in info.workingConditions
select cond.salary
This will return the salary if it exists, or null if any of the prior statements result to null, without throwing an exception.
Is it that much better? No, just saves you the slightest bit of repetition, but it looks cool. It also avoids the overhead of creating all the unused "OrDefault" objects in the accepted answer.

Related

Iterating a expression tree to check for null

I am really struggling to write a generic class, that needs to check if all members of a passed expression are not null, by invoking the actual object.
I am calling the method like:
new TestClass<Class1, Class2>.IsAnyMemberNull(x => x.Property1.List1, object1);
and the Method looks like:
public bool IsAnyMemberNull(Expression<Func<T, IList<TM>>> listExpression, T entityDb)
{
var expressionsToCheck = new List<MemberExpression>();
var expression = listExpression.Body as MemberExpression;
while (expression != null)
{
expressionsToCheck.Add(expression);
expression = expression.Expression as MemberExpression;
}
for (var i = expressionsToCheck.Count - 1; i >= 0; i--)
{
var objectMember = Expression.Convert(expressionsToCheck[i], typeof (object));
var lambda = Expression.Lambda<Func<T, object>>(objectMember);
var value = lambda.Compile().Invoke(entityDb);
if (value == null)
return true;
}
return false;
}
When executing, I get the exception:
incorrect number of parameters supplied for lambda declaration
Any ideas, what I have done wrong?
While it is possible to get your code working, so that correct lambdas are built and compiled, using repeatedly compiled lambdas to achieve null-checking is a costly overkill.
Generally, using lambdas so casually (compiling a lambda for each property in chain and a single object) comes with a notable performance hit. I've run some tests, and on my computer executing this method 1000 times for a given object yielded ~300-700 ms time (depending on the number of properties in the chain). Dunno how many entities you deal with, but it's not a good sign, and better replacements are available. Please read further...
The question is, what are you using this for? That method of yours reminds me of null-conditional operators quite a lot. Generally, if you:
just want to check if any property in the property chain is a null
use C# 6
have all parameter chain lambdas (like x => x.Property1.List1) known at runtime
Then you might scrap all that IsAnyMemberNull method altogether in favour of something like:
object1.Property1.List1 == null
Much more concise and no additional methods are required. I ran it 1 million times and it was still within ~23ms time. It means it's dozens thousands faster than creating all those lambdas.
If you can't use null-coalescing operators for whatever reason (especially when the expression is built dynamically), you might instead decide to use Field/Property reflection.
I took the liberty of removing all that generic class wrapping in favour of a generic method. From your usage example, it seemed the only purpose of the generic class was to access a specific method with class' generic type parameters. It means one new class would have to be made and stored for each variation of the method, for no apparent reason, if I'm not mistaken, for the rest of application's lifetime. Generic methods in specific classes are generally preferred to specific methods in generic classes, in cases like these.
Also, I removed IList, because I see no reason how requiring the last parameter to be of IList type serves the purpose of the function; it only limits its applicability with no apparent gain.
Overall, the result is the following:
public bool IsAnyMemberNull<TEntity, TMember>(Expression<Func<TEntity, TMember>> paramChain, TEntity entityDb)
{
var expressionsToCheck = new List<MemberExpression>();
var expression = paramChain.Body as MemberExpression;
while (expression != null)
{
expressionsToCheck.Add(expression);
expression = expression.Expression as MemberExpression;
}
object value = entityDb;
for (var i = expressionsToCheck.Count - 1; i >= 0; i--)
{
var member = expressionsToCheck[i].Member;
if (member is PropertyInfo) value = (member as PropertyInfo).GetValue(value);
else if (member is FieldInfo) value = (member as FieldInfo).GetValue(value);
else throw new Exception(); // member generally should be a property or field, shouldn't it?
if (value == null)
return true;
}
return false;
}
After running this ~1000 times, it took about 4-6ms; 50-100 times better than lambdas, though null-propagation still reigns supreme.
Called as following (assuming it still resides in TestClass, which it doesn't need to):
new TestClass().IsAnyMemberNull<Class1,Class2>(x => x.Property1.List1, object1);
(Class1 and Class2 might not be necessary, thanks to type inference)
Hope this helps. It's not exactly what you asked for, but I'm afraid with all this lambda-spawning you could run into serious performance issues; especially if this code was to be used many times per request.
You have a problem in lambda expression creation - it is simpler than you thought. You should build lambda for each expressionToCheck with original expression parameter:
for (var i = expressionsToCheck.Count - 1; i >= 0; i--)
{
var lambda = Expression.Lambda<Func<T, object>>(expressionsToCheck[i], listExpression.Parameters);
var value = lambda.Compile().Invoke(entityDb);
if (value == null)
return true;
}

Is there a way to Imitate C# 6 Null-Conditional operator in C# 5

I have a situation where I need to assign some objects' properties inside an object initializer. Some of these objects can be null and I need to access their properties, the problem is that they are too many, and using a if/else thing is not good.
Example
visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV()
{
VisiteId = joined.Visite.VisiteId.ToString(),
NomPointDeVente = joined.VisitePdvProduit.PointDeVente.NomPointDeVente,
});
The joined.VisitePdvProduit can be null, and the problem is that there are like dozens of such assignments (I just took one to shorten the code)
The C# 6 Null-Conditional operator is the perfect solution for this situation, the problem is that I'm on C# 5 in this project, is there a way to imitate that ?
Well, you can use an extension method that receives an accessor delegate and only executes it if the item isn't null:
public static TResult ConditionalAccess<TItem, TResult>(this TItem item, Func<TItem, TResult> accessor) where TResult : Class
{
if (item == null)
{
return null;
}
else
{
return accessor(item);
}
}
You can use it for example like this:
NomPointDeVente = joined.VisitePdvProduit.ConditionalAccess(_ => _.PointDeVente.NomPointDeVente);
You can easily create versions of this method for operations that don't return a value (i.e. bar.ConditionalAccess(_ => _.Foo())) or return value types.
Like this. Ugly, but what had to be done.
visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV()
{
VisiteId = joined.Visite.VisiteId.ToString(),
NomPointDeVente = (joined.VisitePdvProduit == null) ? null : joined.VisitePdvProduit.PointDeVente.NomPointDeVente,
});
If you are talking about the semi-very surprised operator ?., then no. There's no way to mimic the syntax.
What you can do, though, is to create an extension method (or a helper method, static one, preferably) or an instance method working with the properties.
Or, as someone suggested, just use the conditional statement (inline or explicit). But that's not what you're looking for, of course.
One more method (and it's not at all recommendable) is to surround the assignment with a try-catch. But that's really baaad solution and I only mention it for completeness' sake.

Optional Design Pattern, Advantages [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
So, it's pretty well known that the infamous NullReferenceException is the most common exception in software products. I've been reading some articles, and found myself with the Optional approach.
Its aim is to create some kind of encapsulation around a nullable value
public sealed class Optional<T> where T : class {
private T value;
private Optional(T value) {
this.value = value;
}
//Used to create an empty container
public static Optional<T> Empty() {
return new Optional(null);
}
//Used to create a container with a non-null value
public static Optional<T> For(T value) {
return new Optional(value);
}
//Used to check if the container holds a non-null value
public bool IsPresent {
get { return value != null; }
}
//Retrieves the non-null value
public T Value {
get { return value; }
}
}
Afterwards, the now optional value can be returned like this:
public Optional<ICustomer> FindCustomerByName(string name)
{
ICustomer customer = null;
// Code to find the customer in database
if(customer != null) {
return Optional.Of(customer);
} else {
return Optional.Empty();
}
}
And handled like this:
Optional<ICustomer> optionalCustomer = repository.FindCustomerByName("Matt");
if(optionalCustomer.IsPresent) {
ICustomer foundCustomer = optionalCustomer.Value;
Console.WriteLine("Customer found: " + customer.ToString());
} else {
Console.WriteLine("Customer not found");
}
I don't see any improvement, just shifted complexity.
The programmer must remember to check if a value IsPresent, in the same way he must remember to check if a value != null.
And if he forgets, he would get a NullReferenceException on both approaches.
What am I missing? What advantages (if any) does the Optional pattern provide over something like Nullable<T> and the null coalescing operator?
Free your mind
If you think of Option as Nullable by a different name then you are absolutely correct - Option is simply Nullable for reference types.
The Option pattern makes more sense if you view it as a monad or as a specialized collection that contain either one or zero values.
Option as a collection
Consider a simple foreach loop with a list that cannot be null:
public void DoWork<T>(List<T> someList) {
foreach (var el in someList) {
Console.WriteLine(el);
}
}
If you pass an empty list to DoWork, nothing happens:
DoWork(new List<int>());
If you pass a list with one or more elements in it, work happens:
DoWork(new List<int>(1));
// 1
Let's alias the empty list to None and the list with one entry in it to Some:
var None = new List<int>();
var Some = new List(1);
We can pass these variables to DoWork and we get the same behavior as before:
DoWork(None);
DoWork(Some);
// 1
Of course, we can also use LINQ extension methods:
Some.Where(x => x > 0).Select(x => x * 2);
// List(2)
// Some -> Transform Function(s) -> another Some
None.Where(x => x > 0).Select(x => x * 2);
// List()
// None -> None
Some.Where(x => x > 100).Select(x => x * 2);
// List() aka None
// Some -> A Transform that eliminates the element -> None
Interesting side note: LINQ is monadic.
Wait, what just happened?
By wrapping the value that we want inside a list we were suddenly able to only apply an operation to the value if we actually had a value in the first place!
Extending Optional
With that consideration in mind, let's add a few methods to Optional to let us work with it as if it were a collection (alternately, we could make it a specialized version of IEnumerable that only allows one entry):
// map makes it easy to work with pure functions
public Optional<TOut> Map<TIn, TOut>(Func<TIn, TOut> f) where TIn : T {
return IsPresent ? Optional.For(f(value)) : Empty();
}
// foreach is for side-effects
public Optional<T> Foreach(Action<T> f) {
if (IsPresent) f(value);
return this;
}
// getOrElse for defaults
public T GetOrElse(Func<T> f) {
return IsPresent ? value : f();
}
public T GetOrElse(T defaultValue) { return IsPresent ? value: defaultValue; }
// orElse for taking actions when dealing with `None`
public void OrElse(Action<T> f) { if (!IsPresent) f(); }
Then your code becomes:
Optional<ICustomer> optionalCustomer = repository.FindCustomerByName("Matt");
optionalCustomer
.Foreach(customer =>
Console.WriteLine("Customer found: " + customer.ToString()))
.OrElse(() => Console.WriteLine("Customer not found"));
Not much savings there, right? And two more anonymous functions - so why would we do this? Because, just like LINQ, it enables us to set up a chain of behavior that only executes as long as we have the input that we need. For example:
optionalCustomer
.Map(predictCustomerBehavior)
.Map(chooseIncentiveBasedOnPredictedBehavior)
.Foreach(scheduleIncentiveMessage);
Each of these actions (predictCustomerBehavior, chooseIncentiveBasedOnPredictedBehavior, scheduleIncentiveMessage) is expensive - but they will only happen if we have a customer to begin with!
It gets better though - after some study we realize that we cannot always predict customer behavior. So we change the signature of predictCustomerBehavior to return an Optional<CustomerBehaviorPrediction> and change our second Map call in the chain to FlatMap:
optionalCustomer
.FlatMap(predictCustomerBehavior)
.Map(chooseIncentiveBasedOnPredictedBehavior)
.Foreach(scheduleIncentiveMessage);
which is defined as:
public Optional<TOut> FlatMap<TIn, TOut>(Func<TIn, Optional<TOut>> f) where TIn : T {
var Optional<Optional<TOut>> result = Map(f)
return result.IsPresent ? result.value : Empty();
}
This starts to look a lot like LINQ (FlatMap -> Flatten, for example).
Further possible refinements
In order to get more utility out of Optional we should really make it implement IEnumerable. Additionally, we can take advantage of polymorphism and create two sub-types of Optional, Some and None to represent the full list and the empty list case. Then our methods can drop the IsPresent checks, making them easier to read.
TL;DR
The advantages of LINQ for expensive operations are obvious:
someList
.Where(cheapOp1)
.SkipWhile(cheapOp2)
.GroupBy(expensiveOp)
.Select(expensiveProjection);
Optional, when viewed as a collection of one or zero values provides a similar benefit (and there's no reason it couldn't implement IEnumerable so that LINQ methods would work on it as well):
someOptional
.FlatMap(expensiveOp1)
.Filter(expensiveOp2)
.GetOrElse(generateDefaultValue);
Further suggested reading
Option (F#)
When null is not enough (C#)
The neophytes guide to Scala Part 5: The Option type
The Marvel of Monads (C#)
Eric Lippert's series on LINQ and monads
it would probally make more sense if you used something like this
interface ICustomer {
String name { get; }
}
public class OptionalCustomer : ICustomer {
public OptionalCustomer (ICustomer value) {
this.value = value;
}
public static OptionalCustomer Empty() {
return new OptionalCustomer(null);
}
ICustomer value;
public String name { get {
if (value == null ) {
return "No customer found";
}
return value.Name;
}
}
}
now if your pass an "empty" optional customer object you can still call the .Name property (without getting nullpointers)
The advantage of Optional is you know if something may not exist.
The problem with many types of queries that return a null is that that could mean 2 things:
The query didn't return a result
The query returned a result whose value was null.
I know you're asking specifically about C# but Java just introduced Optionals in Java 8 so there are a lot of articles about it so I'll use Java as an example. but it's completely the same idea as in C#:
Consider the Java Map.get(key) method
Object value = map.get(key);
if(value ==null){
//is there an entry in the map key =>null or does key not exist?
}
to get around that you have to have an additional method containsKey( k)
With optional, you only need one method
Optional<Object> result = map.get(key);
if(result.isPresent()){
Object value = result.get();
//if value is null, then we know that key =>null
}
More info see this Java article : http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
Did you mean: Null Object pattern
The article linked to me in the comments contains a conclusion section explained this programming tool.
... The purpose of Optional is not to replace every single null reference in your codebase but rather to help design better APIs in which—just by reading the signature of a method—users can tell whether to expect an optional value. .... deal with the absence of a value; as a result, you protect your code against unintended null pointer exceptions.
Anyway, let it crash and find the reason. If you do not want endlessly embedded if statements than use an implementation pattern Guard Clause pattern, which says the following:
While programs have a main flow, some situations require deviations from the
main flow. The guard clause is a way to express simple and local exceptional
situations with purely local consequences.

Is there a coalesce operator for properties of properties in c#?

So there is the coalescing operator ?? that allows handy handling of null objects (IE. MyDisplayString = MyString ?? "n/a";)
but is there a nice fancy operator for handling a similar situation on properties of objects? For instance lets say that the property you are interested in is a property of a property like: MyDataObject.MySubModel.MyProperty
If MyProperty is null you want coalesce to "n/a". You can use ?? here, but what if MyDataObject is null or MyDataObject.MySubModel?
This also comes up with XML when trying to get optional attributes and elements of an element. IE: MyString = MyElement.Attribute("MyOptionalAttribute").Value ?? "n/a"; fails if the attribute isn't there.
Is there a nice fancy way of handling this scenario?
Is there a nice fancy way of handling
this scenario?
You are not the first one asking for this feature. One way is to write a "With" extension method to fetch property values, since extension methods can handle being called on a null reference. Instead of
thing.Foo.Bar
you would write
thing.With(x => x.Foo).With(x => x.Bar)
In C# 5 and below as stated in other answers you need to build something yourself. Instead of using an Extension method as others have here we use a Helper, that we call NN since we use it a LOT, especially in Razor.
public static TValue N<TParent, TValue>(TParent o, Func<TParent, TValue> accessor, TValue defaultValue)
{
if (o == null)
return defaultValue;
return accessor(o);
}
/// <summary>
/// Guarantees return of null or value, given a prop you want to access, even if the parent in the first argument
/// is null (instead of throwing).
///
/// Usage:
///
/// NN.N(myObjThatCouldBeNull, o => o.ChildPropIWant)
/// </summary>
/// <returns>The value of the prop. Null if the object is null, or if the child prop is null.</returns>
public static TValue N<TParent, TValue>(TParent o, Func<TParent, TValue> accessor)
where TValue : class
{
return NN.N(o, accessor, null);
}
We actually use a few helpers depending on the desired behavior when null is encountered; for example you might be accessing an int property and want 0. Full code in the linked Gist.
In C# 6, you can use the null property coalescence operator:
myObjThatCouldBeNull?.ChildPropIWant
More about it:
https://roslyn.codeplex.com/discussions/540883
The Null Object Pattern
a Null Object is an object with
defined neutral ("null") behavior
may help you avoid this problem.
Another option is to use extension methods, then you can say:
if (Contract
.NullSafe(c => c.Parties)
.NullSafe(p => p.Client)
.NullSafe(c => c.Address) != null)
{
// do something with the adress
Console.Writeline(Contract.Parties.Client.Adress.Street);
}
As I noted here:
Shortcut for "null if object is null, or object.member if object is not null"
this is a fairly frequently requested feature that did not make the bar for C# 4. We'll consider it for hypothetical future versions of the language, but it is not high on the priority list so I would not hold out much hope if I were you.
There might be a better or more elegant way of handling the issue you're describing, but I've found that typically I have to check for nulls along the way, i.e.:
MyString = MyElement.Attribute("MyOptionalAttribute") != null ? MyElement.Attribute("MyOptionalAttribute").Value : "n/a";
In the case of XElement/XAttribute, you can use the explicit conversion operators:
string myString = (string)myElement.Attribute("MyOptionalAttribute") ?? "n/a";
For the general case, a 'safe dereferencing operator' is a fairly frequently requested feature.

Good practices for initialising properties?

I have a class property that is a list of strings, List.
Sometimes this property is null or if it has been set but the list is empty then count is 0.
However elsewhere in my code I need to check whether this property is set, so currently my code check whether it's null and count is 0 which seems messy.
if(objectA.folders is null)
{
if(objectA.folders.count == 0)
{
// do something
}
}
Any recommendation on how this should be handled?
Maybe I should always initialise the property so that it's never null?
When I have List as a property, I usually have something that looks like the following (this is not a thread safe piece of code):
public class SomeObject
{
private List<string> _myList = null;
public List<string> MyList
{
get
{
if(_myList == null)
_myList = new List<string>();
return _myList;
}
}
}
Your code would then never have to check for null because the Property would be initialized if used. You would then only have to check for the Count.
Right now your code will Always throw a Null Pointer exception, you are checking for Null and if it IS null - you're trying to access an object which does not exist.
If for your application the collection being a null reference never has a different meaning than the collection being empty, then yes, I would say you should always initialize it and this way remove the null checks from the remaining code.
This approach only makes sense if the property setter does not allow to change it to a null reference after initialization.
You have three options (and you need to decide based on your project):
Create a method to check for NullOrNoElements. Pro: Allows both null and no entries. Con: You have to call it everywhere you want to use the property.
Preinitialize with a list. Pro: Thread-save and very easy. Con: will use memory even when not used (depending on how many instances you have this may be a problem)
Lazy initialize Pro: Does only use memory when really used. Con: NOT thread save.
private List<string> lp = null;
public List<string> ListProp
{
get
{
if(lp == null)
lp = new List<string>();
return lp;
}
}
You could always initialize the property so it's an empty List. Then you can just check the count property.
List<String> Folder = Enumerable.Empty<String>();
I once wrote an extension method for ICollection objects that checked if they were null or empty
public static Boolean IsNullOrEmpty<T>(this ICollection<T> collection)
{
return collection == null ? true : collection.Count() == 0;
}
public static Boolean IsPopulated<T>(this ICollection<T> collection)
{
return collection != null ? collection.Count() > 0 : false;
}
You could do this in a single IF
if(objectA.folders is null || objectA.folders.count == 0)
Or you could create a boolean property in the class which checks this status for you and returns a result
public bool objectA.FolderIsNullOrEmpty
{
get { return objectA.folders is null || objectA.folders.count == 0;}
}
If it does not make a difference to your application, I would rather recomend initializing the List to start with.
You could handle this by initializing the object in the constructor. This is usually where this type of thing is done. Although I see nothing wrong with your current code. No point in initializing stuff that doesn't exist yet, it just wastes memory.
Its a good question. I would add a method to objectA FoldersNullOrEmpty() that you can use eg
public virtual FoldersNullOrEmpty()
{
return (folders == null || folders.count == 0)
}
I almost always initialize lists and even make sure they can't be set to null if exposed by any setters. This makes using them much easier.

Categories

Resources