¿Cómo usar Expression Tree para acceder de forma segura a la ruta de objetos anulables?

Cuando obtengo un resultado XML deserializado en un árbol de objetos generado por xsd y quiero usar algún objeto profundo dentro de ese árbol a.b.c.d.e.f, me dará una excepción si falta algún nodo en esa ruta de consulta.

if(a.b.c.d.e.f != null)
    Console.Write("ok");

Quiero evitar buscar nulos para cada nivel como este:

if(a != null)
if(a.b != null)
if(a.b.c != null)
if(a.b.c.d != null)
if(a.b.c.d.e != null)
if(a.b.c.d.e.f != null)
    Console.Write("ok");

La primera solución es implementar el método de extensión Get que permite esto:

if(a.Get(o=>o.b).Get(o=>o.c).Get(o=>o.d).Get(o=>o.e).Get(o=>o.f) != null)
    Console.Write("ok");

La segunda solución es implementar el método de extensión Get (string) y usar la reflexión para obtener un resultado como este:

if(a.Get("b.c.d.e.f") != null)
    Console.Write("ok");

La tercera solución podría ser implementar ExpandoObject y usar el tipo dinámico para obtener un resultado como este:

dynamic da = new SafeExpando(a);
if(da.b.c.d.e.f != null)
    Console.Write("ok");

Pero las últimas 2 soluciones no brindan los beneficios de una escritura fuerte e IntelliSense.

Creo que lo mejor podría ser la cuarta solución que se puede implementar con Expression Trees:

if(Get(a.b.c.d.e.f) != null)
    Console.Write("ok");

o

if(a.Get(a=>a.b.c.d.e.f) != null)
    Console.Write("ok");

Ya implementé la primera y la segunda solución.

Así es como se ve la primera solución:

[DebuggerStepThrough]
public static To Get<From,To>(this From @this, Func<From,To> get)
{
    var ret = default(To);
    if(@this != null && [email protected](default(From)))
        ret = get(@this);

    if(ret == null && typeof(To).IsArray)
        ret = (To)Activator.CreateInstance(typeof(To), 0);

    return ret;
}

¿Cómo implementar la cuarta solución si es posible?

También sería interesante ver cómo implementar la tercera solución si es posible.

Respuestas a la pregunta(1)

Su respuesta a la pregunta