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
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.