C# 执行链式空检查的优雅方法

C# 执行链式空检查的优雅方法,c#,lambda,C#,Lambda,我使用此解决方案在代码中执行链式空检查 我只是想知道我们能不能这样做 bool returnValue = Helper.IsNull(nullPerson.contact.address.city); 那不是更干净吗 我试着编写这样一个泛型函数 public static bool IsNull<T>(this T rootObj) { var visitor = new IsNullExpressionVisitor(); //... //... } publi

我使用此解决方案在代码中执行链式空检查

我只是想知道我们能不能这样做

bool returnValue = Helper.IsNull(nullPerson.contact.address.city);
那不是更干净吗

我试着编写这样一个泛型函数

public static bool IsNull<T>(this T rootObj)
{
  var visitor = new IsNullExpressionVisitor();
  //...
  //...
}
public static bool为空(此T rootObj)
{
var visitor=新的IsNullExpressionVisitor();
//...
//...
}
但是后来我被困在如何从这个rootObject生成表达式的问题上。

一种方法是使用

使用它,代码将变成这样(您可能喜欢,也可能不喜欢!):

然而,高兴是因为

使用此新的
?。
运算符,代码如下所示:

city = nullPerson?.address?.city;
city = selectedPerson.Contact.Address.City;
(*据称…

在阅读了试图解决相同问题的文章后,我会冒险说,目前没有办法创建真正优雅的链式空检查,优雅意味着不向链的每个组件添加间接寻址

在lambda评估中包装链可能是当时最不可怕的方法,并且它只在以下情况下起作用:

CheckNull<string>(() => nullPerson.contact.address.city);

T CheckNull<T>(Func<T> f) { try { return f(); } catch { return default(T); } }
CheckNull(()=>nullPerson.contact.address.city);
T CheckNull(Func f){try{return f();}catch{return default(T);}}

我宁愿鼓励您尝试并遵循这样的规则,即您的对象不应该知道它正在处理的对象的内部工作方式,并要求它们以任何方式返回值,而不是按照类树返回值。

不,没有。我看到的所有现有解决方案都远比问题更可怕。很多聪明的解决方案只是让其他人很难理解代码在做什么

情况是,您希望执行以下操作:

city = nullPerson?.address?.city;
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;
    }
}
毕竟,由于想要进入这条长长的房地产链的本质,你确实有一个选定城市的概念。代码并不优雅,但至少它隐藏在一个地方,任何阅读它的人都可以立即理解“SelectedCity”是什么。

在这里查看我的答案

您可以简单地编写小型扩展方法,这样就可以编写链式lambda:

city = nullPerson?.address?.city;
city = selectedPerson.Contact.Address.City;
var val=instance.DefaultOrValue(x=>x.SecondInstance).DefaultOrValue(x=>x.ThirdInstance).DefaultOrValue(x=>x.Value)


您可以将此方法命名为更简短的方法

我认为没有任何方法可以使用此签名。但你可能会有更好的运气通过一个lambda。如下所示:IsNull(()=>nullPerson.contact.address.city)。根据您使用的dotnet版本,您可以使用静态类约定,如果存在null值,您希望链中的返回值是什么
nullPerson.contact.address.city
?请尝试以下操作:@TonyHopkinson很明显,OP想要处理他的一个链为null,但你为什么称之为“移动/隐藏真实问题”?真正的问题是什么?唉,我不相信这个功能真的能进入C#6。。。也许是C#7?难道没有一个用户声音,我们可以在哪里推动接线员吗?@samy:)我猜当它开始被滥用时,人们会很快停止欢欣……@TonyHopkinson是的,我知道它会鼓励火车失事。:)除了处理错误=)之外,使用catch实际上是一种不好的做法,但您的方法与我的解决方案非常接近: