Skip to content

Instantly share code, notes, and snippets.

@JoeRobich
Created July 11, 2013 20:32
Show Gist options
  • Save JoeRobich/5978981 to your computer and use it in GitHub Desktop.
Save JoeRobich/5978981 to your computer and use it in GitHub Desktop.
Use Linq expressions to test for `null`s in chained member access. For instance `ValidateNotNull(() => person.Address.State);` would return false if `person`, `person.Address`, or `person.Address.State` were `null`.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace TestNullCheckingExpressions
{
class Program
{
static void Main(string[] args)
{
var person = new Person { Name = "Joey", Address = new Address() { State = "TN" } };
Console.WriteLine("person != null => " + ValidateNotNull(() => person));
Console.WriteLine("person.Name != null => " + ValidateNotNull(() => person.Name));
Console.WriteLine("person.Address != null => " + ValidateNotNull(() => person.Address));
Console.WriteLine("person.Address.State != null => " + ValidateNotNull(() => person.Address.State));
Console.WriteLine("person.Address.Street != null => " + ValidateNotNull(() => person.Address.Street));
Console.WriteLine("");
Console.WriteLine("Press Enter to exit");
Console.ReadLine();
}
static bool ValidateNotNull(Expression<Func<object>> exp)
{
var members = new List<MemberExpression>();
FindMemberAccess(((LambdaExpression)exp).Body, members);
if (members.Count == 0)
return false;
var constant = members[0].Expression as ConstantExpression;
object value = constant.Value;
foreach (var member in members)
{
value = member.GetValue(value);
if (value == null)
return false;
}
return true;
}
private static void FindMemberAccess(Expression expression, List<MemberExpression> members)
{
var memberExpress = expression as MemberExpression;
if (memberExpress != null)
{
FindMemberAccess(memberExpress.Expression, members);
members.Add(memberExpress);
}
}
}
static class MemberExpressionExtensions
{
public static object GetValue(this MemberExpression memberExpression, object obj)
{
if (memberExpression.Member.MemberType == System.Reflection.MemberTypes.Field)
{
var field = obj.GetType().GetField(memberExpression.Member.Name);
return field.GetValue(obj);
}
else if (memberExpression.Member.MemberType == System.Reflection.MemberTypes.Property)
{
var property = obj.GetType().GetProperty(memberExpression.Member.Name);
return property.GetValue(obj);
}
return null;
}
}
class Person
{
public string Name { get; set; }
public Address Address {get; set;}
}
class Address
{
public string Street { get; set; }
public string State { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment