Ответ 1
Нет, нет.
Единственное, что может помочь, - это оценить, действительно ли DoStuff
в правильном классе.
Возможный дубликат:
Глубокая проверка нулей, есть ли лучший способ?
например, если вы выполняете логику в Foo1.Bar1.Foo2.Bar2 (и каждое из свойств может быть нулевым), вы не можете просто сделать это с foo.Bar1.Foo2.Bar2, потому что это возможно что вы получите нулевое ссылочное исключение
В настоящее время это то, что я делаю
if (foo1!=null && foo1.Bar1!=null && foo1.Bar1.Foo2 !=null && foo1.Bar1.Foo2.Bar2!=null)
return DoStuff(foo1.Bar1.Foo2.Bar2); //actually a logic based on the value of Bar2
else return null;
Есть ли более элегантный или удобный способ, чтобы сделать это?
Нет, нет.
Единственное, что может помочь, - это оценить, действительно ли DoStuff
в правильном классе.
этот метод расширения работает, но не является классным кодом или может его улучшить:
public static bool AnyNull<TSource, TResult>(this TSource source, Func<TSource, TResult> selector)
{
try
{
selector(source);
return false; ;
}
catch { return true; }
}
используйте его:
if(!foo1.AnyNull(p=>p.Bar1.Foo2.Bar2))
DoStuff(foo1.Bar1.Foo2.Bar2)
Нет, к сожалению, нет. Я тоже часто хотел упрощенного синтаксиса!
Однако здесь довольно приличная альтернатива, с которой я столкнулся: создайте вспомогательный метод Null-Safe-Chain. Вот как это выглядит:
var bar2 = NullSafe.Chain(foo1, f1=>f1.Bar1, b1=>b1.Foo2, f2=>f2.Bar2);
Здесь метод:
public static TResult Chain<TA,TB,TC,TResult>(TA a, Func<TA,TB> b, Func<TB,TC> c, Func<TC,TResult> r)
where TA:class where TB:class where TC:class {
if (a == null) return default(TResult);
var B = b(a);
if (B == null) return default(TResult);
var C = c(B);
if (C == null) return default(TResult);
return r(C);
}
Я также создал кучу перегрузок (с 2-6 параметрами). Это действительно хорошо для меня!