在if语句中缩短/避免级联空值检查的方法

时间:2013-07-15 15:27:26

标签: coding-style

我有这个条件

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

问题是,我认为这很难看。我可以编写一个封装它的函数,但我想知道是否有其他东西可以帮助我编写类似下面的重要位而不必进行空检查。如果没有,那么这将是一个方便的语言扩展。

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

1 个答案:

答案 0 :(得分:4)

对于c#这两个选项实现了你想要的东西,但我不会很快将它放在我的软件中。 此外,我怀疑这是否更具可读性或更易理解。还有一个选项,但需要您重构Model类链。如果您为Bids中的类型实现NullObjectItem中的类型可以执行if(Model.Bids.Items.Count > 0),因为所有类型都不会为null但具有处理空的实现state(很像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");
}