更清洁的方式做在C#中的空检查?清洁、方式

由网友(- 只是喜欢不敢奢求永远)分享简介:假设,我有这个接口,interface IContact{IAddress address { get; set; }}interface IAddress{string city { get; set; }}class Person : IPerson{public IContact contact {...

假设,我有这个接口,

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);
    }
}
阅读全文

相关推荐

最新文章