Way to shorten/avoid cascaded null checks in if-statements

后端 未结 1 801
别那么骄傲
别那么骄傲 2021-01-20 02:13

I have this condition

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

Problem

相关标签:
1条回答
  • 2021-01-20 02:57

    For c# this two options achieve sort of what you want but I wouldn't put this in my software quickly. Also I doubt this gets more readable or better understandable. There is one other option but that requires you to refactor you Model class chain. If you implement a NullObject for the type in Bids and the type in Item you can do if(Model.Bids.Items.Count > 0) because all types will not be null but have an implementation that handles the Empty state (much like String.Empty)

    helpers

    /* 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));
    }
    

    Usage

    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");
    }
    
    0 讨论(0)
提交回复
热议问题