よりスリムにnull チェックを行う
.net 4.0 - Cleaner way to do a null check in C#? - Stack Overflow
Sansan公式メディア「mimi」
でCheckNullが気持ち悪いので消してみた。+αデフォルト値を返せるようにしてみた
using System; using System.Diagnostics; using System.Linq.Expressions; using System.Reflection; namespace IsNullTest { public class IsNullVisitor : ExpressionVisitor { public bool IsNull { get { return null == CurrentObject; } } public object CurrentObject { get; set; } protected override Expression VisitMember(MemberExpression node) { base.VisitMember(node); if (!IsNull) { var member = (PropertyInfo)node.Member; CurrentObject = member.GetValue(CurrentObject, null); } return node; } } public static class Helper { public static bool IsNull<T>(this T root, Expression<Func<T, object>> getter) { var visitor = new IsNullVisitor() { CurrentObject = root }; visitor.Visit(getter); return visitor.IsNull; } public static U IfNull<T, U>(this T root, U defaultValue, Expression<Func<T, U>> getter) { var visitor = new IsNullVisitor() { CurrentObject = root }; visitor.Visit(getter); if (visitor.IsNull) { return defaultValue; } else { return (U)visitor.CurrentObject; } } } class Contact { public Address address { get; set; } } class Address { public string city { get; set; } public int integer { get; set; } public float real { get; set; } } class Person { public Contact contact { get; set; } } class Program { static void Main(string[] args) { Person nullPerson = null; Debug.Assert(true == nullPerson.IsNull(p => p.contact.address.city)); Debug.Assert(true == new Person().IsNull(p => p.contact.address.city)); Debug.Assert(true == new Person { contact = new Contact() }.IsNull(p => p.contact.address.city)); Debug.Assert(true == new Person { contact = new Contact { address = new Address() } }.IsNull(p => p.contact.address.city)); Debug.Assert(true == nullPerson.IsNull(p => p)); Debug.Assert(true == nullPerson.IsNull(p => p.contact)); Debug.Assert(false == new Person { contact = new Contact { address = new Address { city = "LONDON" } } }.IsNull(p => p.contact.address.city)); Debug.Assert("NY" == nullPerson.IfNull("NY", p => p.contact.address.city)); Debug.Assert(true == nullPerson.IsNull(p => p.contact.address.integer)); Debug.Assert(100 == nullPerson.IfNull(100, p => p.contact.address.integer)); Debug.Assert(false == new Person { contact = new Contact { address = new Address { integer = 100 } } }.IsNull(p => p.contact.address.integer)); Debug.Assert(100 == new Person { contact = new Contact { address = new Address { integer = 100 } } }.IfNull(0, p => p.contact.address.integer)); Debug.Assert(0.1f == nullPerson.IfNull(0.1f, p => p.contact.address.real)); Debug.Assert(0.1f == new Person { contact = new Contact { address = new Address { real = 0.1f } } }.IfNull(0, p => p.contact.address.real)); } } }