2010-09-28 51 views
3

初始化底层对象有人问我,什么是错/如何能在以下情形可以固定扩展“WhenNull”检查null并通过拉姆达

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

// instead of 
Customer customer = null; 
if (customer == null) 
{ 
    customer = new Customer(); 
} 
customer.Foo(); 

一位开发商向我WhenNull延长他的版本

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; 
} 

他的问题/意图是,他不希望指定lambda表达式的基本对象(在这种情况下,“客户”)

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

我认为这是做不到的。
这是正确的吗?

+1

我迷路了一下 - 你想达到哪一个?哪一个是错的? – Grzenio 2010-09-28 10:58:57

回答

7

你可以这样做:

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

还注意到:你想用Func<T>Action<T>按您的示例代码。

编辑2:

你可能想这样的:

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; 
} 

用法:

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

用于添加“类”约束的+1。但是,第二个变体中不应该需要'new()'约束。 – Lucero 2010-09-28 11:11:15

2

如果你真的想简写语法,你可能只是做:

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

不会回复修改它虽然。

+0

或者客户(客户=新客户())。Foo() – veggerby 2010-09-28 11:07:58

0

你可以使用函数功能< T>代替:

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(); 
} 

或者作为leppie州使用合并运算符和新的()contraint如果你不想指定兰巴。

+1

不可以,但应该!:) – leppie 2010-09-28 11:09:05

+0

@leppie true :) – veggerby 2010-09-28 11:10:47