Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test if parent objects exists

I am using a lot of database data in my project that is exported in different classes. For example, I have

transaction.Layout.Multimedia.Images.first();

The problem is that these properties are not necessarily available.

So, it is possible that transaction.Layout is null, it is possible that transaction.Layout.Multimedia is null, and so on.

I currently use this for every property:

if (transaction.Layout != null)
{
    if (transaction.Layout.Multimedia != null)
    {
        if (transaction.Layout.Multimedia.Images != null)
        {
            if (transaction.Layout.Multimedia.Images.count > 0)
            {
                var img = transaction.Layout.Multimedia.Images.first();
            }
        }
    }
}

I was wondering if there is a better way that I can check all parent classes to make sure that the property I need is available. These aren't the only objects I use, there are others as well with totally different names.

Thanks in advance

like image 811
Jerodev Avatar asked Apr 30 '26 22:04

Jerodev


2 Answers

No, there is not yet. The new version of .NET (Roslyn) has the Null propagating operator.

Then you could do:

if (transaction?.Layout?.Multimedia?.Image?.count > 0)
{
    var img = transaction.Layout.Multimedia.Images.first();
}

For now, we are stuck with this. You could minimize the rows needed by concatenating the checks, like this:

if ( transaction.Layout != null
     && transaction.Layout.Multimedia != null
     && transaction.Layout.Multimedia.Images != null
     && transaction.Layout.Multimedia.Images.count > 0
   )
{
    var img = transaction.Layout.Multimedia.Images.first();
}

There is nothing more to do.

like image 91
Patrick Hofman Avatar answered May 03 '26 12:05

Patrick Hofman


You can try to use Maybe monad. More detailed description is given at Chained null checks and the Maybe monad

With and If extension methods would allow you to write:

var img = transaction.With(x => x.Layout)
                     .With(x => x.Multimedia)    
                     .With(x => x.Images)
                     .If(x => x.count > 0))
                     .With(x => x.first());

With method looks like:

public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
  where TResult : class where TInput : class
{
  if (o == null) return null;
  return evaluator(o);
}

If method:

public static TInput If<TInput>(this TInput o, Func<TInput, bool> evaluator) 
  where TInput : class
{
  if (o == null) return null;
  return evaluator(o) ? o : null;
}
like image 42
Ilya Ivanov Avatar answered May 03 '26 11:05

Ilya Ivanov