Is it acceptable to use exceptions instead of verbose null-checks?

前端 未结 9 2378
刺人心
刺人心 2020-12-28 21:51

I recenly encountered this problem in a project: There\'s a chain of nested objects, e.g.: class A contains an instance variable of class B, which in turns has an instance v

9条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-28 22:19

    Personally I like to avoid this problem altogether by using an option type. By adjusting the value returned from these methods/properties to be Option rather than T the caller can choose how they wish to handle the case of no value.

    An option type can either have a contained value or not (but the option itself can never be null), but the caller cannot simply pass it on without unwrapping the value so it forces the caller to deal with the fact there may be no value.

    E.g. in C#:

    class A {
        Option B { get { return this.optB; } }
    }
    
    class B {
        Option C { get { return this.optC; } }
    }
    
    // and so on
    

    If the caller wants to throw, they merely retrieve the value without explicitly checking to see if there is one:

    A a = GetOne();
    D d = a.Value.B.Value.C.Value.D.Value; // Value() will throw if there is no value
    

    If the caller wants to just default if any step doesn't have a value, they can perform mapping/binding/projection:

    A a = GetOne();
    D d = a.Convert(a => a.B) // gives the value or empty Option
           .Convert(b => b.C) // gives value or empty Option
           .Convert(c => c.D) // gives value or empty Option
           .ValueOrDefault(new D("No value")); // get a default if anything was empty 
    

    If the caller wants to default at each stage, they can:

    A a = GetOne();
    D d = a.ValueOrDefault(defaultA)
         .B.ValueOrDefault(defaultB)
         .C.ValueOrDefault(defaultC)
         .D.ValueOrDefault(defaultD);
    

    Option is not currently part of C# but I imagine one day will be. You can get an implementation by referencing the F# libraries or you may be able to find an implementation on the web. If you'd like mine, let me know and I'll send it to you.

提交回复
热议问题