更清洁的方式做在C#中的空检查?
假设,我有这个接口,
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
(这工作,检查城市为空或不是。)
Person.Contact.Address.City != null
(This works to check if City is null or not.)
不过,这种检查失败,如果地址或联系方式或人本身就是空。
However, this check fails if Address or Contact or Person itself is null.
目前,一种解决办法我能想到的是这样的:
Currently, one solution I could think of was this:
if (Person != null && Person.Contact!=null && Person.Contact.Address!= null && Person.Contact.Address.City != null)
{
// Do some stuff here..
}
是否有这样做的更清洁的方式?
Is there a cleaner way of doing this?
我真的不喜欢空
检查正在做的(东西== NULL)
。相反,有另一种很好的方式做一些事情,如 something.IsNull()
的方法?
I really don't like the null
check being done as (something == null)
. Instead, is there another nice way to do something like the something.IsNull()
method?
在一个通用的方法,你可以使用一个前pression树,并检查与扩展方法:
In a generic way, you may use an expression tree and check with an extension method:
if (!person.IsNull(p => p.contact.address.city))
{
//Nothing is null
}
全部code:
Full code:
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);
}
}