开发者

Extension "WhenNull" to check for null and init the underlying object via lambda

I was asked whats wrong/how can the following scenario can be fixed

Customer customer = null;
customer.WhenNull(c => new Customer())
        .Foo();

// instead of
Customer customer = null;
if (customer == null)
{
   customer = new Customer();
}
customer.Foo();开发者_JS百科

One developer sends me his Version of the WhenNull extension

public static T WhenNull<T>(this T source, Action<T> nullAction)
{
   if (source != null)
   {
      return source;
   } 

   if (nullAction == null)
   {
       throw new ArgumentNullException("nullAction");
   }

   nullAction(source);

   return source;
}

His problem / intention is, that he doesn't want to specify the underlying object in the lambda expression (in this case "customer")

Customer customer = null;
customer.WhenNull(c => customer = new Customer())
        .Foo();

I thought this can't be done.

Is this correct?


You could do:

static T WhenNull<T>(this T t) where T : class, new()
{
  return t ?? new T();
}

Also noted: You want to use Func<T> not Action<T> as per your example code.

Edit 2:

You probably want this:

static T WhenNull<T>(this T t, Func<T> init) where T : class
{
  if (t == null)
  {
    t = init();  // could return here, but for debugging this is easier
  }
  return t;
}

Usage:

something.WhenNull(() => new Something()).Foo()


If you really want shorthand syntax, you could just do:

(customer = customer ?? new Customer()).Foo();

Wouldn't recommend it though.


You could use Func<T> instead:

public static T WhenNull<T>(this T source, Func<T> nullFunc)
{
   if (source != null)
   {
      return source;
   } 

   if (nullFunc == null)
   {
       throw new ArgumentNullException("nullFunc");
   }

   return nullFunc();
}

Or as leppie states use the coalescing operator and the new() contraint if you do not want to specify the lamba.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜