2013-07-15 43 views
3

我有這個條件方式來縮短/避免級聯的if語句

if(Model.Bids != null && Model.Bids.Items != null && Model.Bids.Items.Count > 0) 
{ 
    ... 
} 

問題是null檢查,我認爲這是醜陋的。我可以編寫一個封裝了這個函數的函數,但是我不知道是否還有別的東西可以幫助我寫下類似下面的重要位,而不必執行空檢查。如果不是,那麼這將是一個方便的語言擴展。

if(Model.Bids.Items.Count > 0) 
{ 
    ... 
} 
+0

這是什麼語言?你可能可以用壓抑或try catch塊來做到這一點 – exussum

回答

4

對於c#這兩個選項實現你想要的,但我不會把它放在我的軟件快速。 另外我懷疑這會變得更具可讀性或更好理解。還有一個選擇,但這需要你重構你的模型類鏈。如果您實現一個NullObjectBids和類型Item你可以做if(Model.Bids.Items.Count > 0)因爲所有類型都不能爲空,但有一個處理空狀態(很像的String.Empty)

助手的實現類型

/* take a func, wrap in a try/catch, invoke compare */ 
bool tc(Func<bool> comp) 
{ 
    try 
    { 
     return comp.Invoke(); 
    } 
    catch (Exception) 
    { 
     return false; 
    } 
} 

/* helper for f */ 
T1 f1<T,T1>(T root, Func<T, T1> p1) where T:class 
{ 
    T1 res = default(T1); 
    if (root != null) 
    { 
     res = p1.Invoke(root); 
    } 
    return res; 
} 

/* take a chain of funcs and a comp if the last 
    in the chain is still not null call comp (expand if needed) */ 
bool f<T,T1,T2,TL>(T root, Func<T,T1> p1, Func<T1,T2> p2, Func<T2,TL> plast, 
     Func<TL, bool> comp) where T:class where T1:class where T2:class 
{ 
    var allbutLast = f1(f1(root, p1), p2); 
    return allbutLast != null && comp(plast.Invoke(allbutLast)); 
} 

使用

var m = new Model(); 
if (f(m, p => p.Bids, p => p.Items, p => p.Count, p => p > 0)) 
{ 
    Debug.WriteLine("f"); 
} 
if (tc(() => m.Bids.Items.Count > 0)) 
{ 
    Debug.WriteLine("tc "); 
} 
if (m.Bids != null && m.Bids.Items != null && m.Bids.Items.Count > 0) 
{ 
    Debug.WriteLine("plain"); 
}