Is there such a thing as a chained NULL check?

前端 未结 7 451
灰色年华
灰色年华 2021-01-18 05:30

I have the following ugly code:

if (msg == null || 
    msg.Content == null || 
    msg.Content.AccountMarketMessage == null || 
    msg.Content.AccountMarke         


        
7条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-18 06:12

    You can lazily evaluate the values using lambda expressions. This is overkill for a simple null check, but can be useful for chaining more complex expressions in a "fluent" manner.

    Example

    // a type that has many descendents
    var nested = new Nested();
    
    // setup an evaluation chain
    var isNull =
        NullCheck.Check( () => nested )
            .ThenCheck( () => nested.Child )
            .ThenCheck( () => nested.Child.Child )
            .ThenCheck( () => nested.Child.Child.Child )
            .ThenCheck( () => nested.Child.Child.Child.Child );
    
    // handle the results
    Console.WriteLine( isNull.IsNull ? "null" : "not null" );
    

    Code

    This is a full example (albeit draft-quality code) that can be pasted into a console app or LINQPad.

    public class Nested
    {
      public Nested Child
      {
          get;
          set;
      }
    }
    
    public class NullCheck
    {
       public bool IsNull { get; private set; }
    
       // continues the chain
       public NullCheck ThenCheck( Func test )
       {
           if( !IsNull )
           {
               // only evaluate if the last state was "not null"
               this.IsNull = test() == null;
           }
    
           return this;
       }
    
       // starts the chain (convenience method to avoid explicit instantiation)
       public static NullCheck Check( Func test )
       {
           return new NullCheck { IsNull = test() == null };
       }
    }
    
    private void Main()
    {
       // test 1
       var nested = new Nested();
       var isNull =
           NullCheck.Check( () => nested )
               .ThenCheck( () => nested.Child )
               .ThenCheck( () => nested.Child.Child )
               .ThenCheck( () => nested.Child.Child.Child )
               .ThenCheck( () => nested.Child.Child.Child.Child );
    
       Console.WriteLine( isNull.IsNull ? "null" : "not null" );
    
       // test 2
       nested = new Nested { Child = new Nested() };
       isNull = NullCheck.Check( () => nested ).ThenCheck( () => nested.Child );
    
       Console.WriteLine( isNull.IsNull ? "null" : "not null" );
    
       // test 3
       nested = new Nested { Child = new Nested() };
       isNull = NullCheck.Check( () => nested ).ThenCheck( () => nested.Child ).ThenCheck( () => nested.Child.Child );
    
       Console.WriteLine( isNull.IsNull ? "null" : "not null" );
    }
    
    
    

    Again: you probably shouldn't use this in lieu of simple null checks due to the complexity it introduces, but it's an interesting pattern.

    提交回复
    热议问题