假设,我有这个界面,
interface IContact { IAddress address { get; set; } } interface IAddress { string city { get; set; } } class Person : IPerson { public IContact contact { get; set; } } class test { private test() { var person = new Person(); if (person.contact.address.city != null) { //this will never work if contact is itself null? } } }
Person.Contact.Address.City != null(这可以检查 City 是否为空。)
Person.Contact.Address.City != null
但是,如果 Address 或 Contact 或 Person 本身为空,则此检查失败。
目前,我能想到的一种解决方案是:
if (Person != null && Person.Contact!=null && Person.Contact.Address!= null && Person.Contact.Address.City != null) { // Do some stuff here.. }
有更清洁的方法吗?
我真的不喜欢做null检查(something == null)。相反,是否有另一种好方法来做类似该something.IsNull()方法的事情?
null
(something == null)
something.IsNull()
通常,您可以使用表达式树并使用扩展方法进行检查:
if (!person.IsNull(p => p.contact.address.city)) { //Nothing is null }
完整代码:
public class IsNullVisitor : ExpressionVisitor { public bool IsNull { get; private set; } public object CurrentObject { get; set; } protected override Expression VisitMember(MemberExpression node) { base.VisitMember(node); if (CheckNull()) { return node; } var member = (PropertyInfo)node.Member; CurrentObject = member.GetValue(CurrentObject,null); CheckNull(); return node; } private bool CheckNull() { if (CurrentObject == null) { IsNull = true; } return IsNull; } } public static class Helper { public static bool IsNull<T>(this T root,Expression<Func<T, object>> getter) { var visitor = new IsNullVisitor(); visitor.CurrentObject = root; visitor.Visit(getter); return visitor.IsNull; } } class Program { static void Main(string[] args) { Person nullPerson = null; var isNull_0 = nullPerson.IsNull(p => p.contact.address.city); var isNull_1 = new Person().IsNull(p => p.contact.address.city); var isNull_2 = new Person { contact = new Contact() }.IsNull(p => p.contact.address.city); var isNull_3 = new Person { contact = new Contact { address = new Address() } }.IsNull(p => p.contact.address.city); var notnull = new Person { contact = new Contact { address = new Address { city = "LONDON" } } }.IsNull(p => p.contact.address.city); } }