2010-09-28 32 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