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.
精彩评论