我正在使用此解决方案在我的代码中进行链式空检查
Cleaner way to do a null check in C#?
我只是想知道我们不能这样做。
bool returnValue = Helper.IsNull(nullPerson.contact.address.city);
那会更清洁吗?
我尝试编写这样的通用函数
public static bool IsNull<T>(this T rootObj)
{
var visitor = new IsNullExpressionVisitor();
//...
//...
}
但后来我不知道如何从这个rootObject中创建表达式。
答案 0 :(得分:4)
解决这个问题的一种方法(尽管仍然有点笨拙)是使用a construct that's sometimes called a "Maybe" monad。
使用它,代码会变成这样的东西(你可能喜欢也可能不喜欢!):
string city = nullPerson.With(x => x.address)
.With(x => x.city);
然而,因为C# is getting the "Safe Navigation" operator (?.
) in the next version*.
使用这个新的?.
运算符,代码如下所示:
city = nullPerson?.address?.city;
(*据称...)
答案 1 :(得分:1)
在阅读many questions试图解决同样的问题之后,我会想出来并且说目前无法创建真正优雅的链接null检查,优雅意味着不向链的每个组件添加间接。
在lambda评估中包装链可能是当时最不可行的方式,它只适用于:
CheckNull<string>(() => nullPerson.contact.address.city);
T CheckNull<T>(Func<T> f) { try { return f(); } catch { return default(T); } }
我宁愿鼓励你尝试按照Law of Demeter说明你的对象不应该知道它正在使用的对象的内部工作方式,并要求他们以任何他们想要的方式返回值而不是走下课堂树。
答案 2 :(得分:0)
不,没有。我见过的所有现有解决方案都远比问题困难得多。很多聪明的解决方案让其他人很难理解代码在做什么。
情况是你想做这样的事情:
city = selectedPerson.Contact.Address.City;
您可以做的是将支票封装在一个属性
中City SelectedCity
{
get
{
if (selectedPerson == null || selectedPerson.Contact == null || selectedPerson.Contact.Address == null)
return null;
return selectedPerson.Contact.Address.City;
}
}
毕竟,想要访问这个长链属性的本质就是你有一个选定城市的概念。代码并不优雅,但至少它隐藏在一个地方,阅读它的任何人都可以立即掌握一个&#34; SelectedCity&#34;是
答案 3 :(得分:0)
在这里查看我的答案
https://stackoverflow.com/a/34086283/4711853
你可以简单地编写一个小的扩展方法,它可以让你像这样编写链式lambda:
var val = instance.DefaultOrValue(x =&gt; x.SecondInstance).DefaultOrValue(x =&gt; x.ThirdInstance).DefaultOrValue(x =&gt; x.Value);
您可以将此方法命名为