Null coalescing within an invocation chain

偶尔善良 提交于 2019-12-01 11:27:11

You're looking for the .? operator (or is it ?.—one of those, anyway), which does not exist in C# (though it is an often-requested feature, according to Eric Lippert).

The only possible suggestion I have is to write a method that takes an expression and uses it to check for any nulls. But this will come at a performance cost. Anyway, it might look like:

T TryOrDefault<T>(Expression<Func<T>> expression)
{
    // Check every MemberExpression within expression one by one,
    // looking for any nulls along the way.

    // If a null is found, return default(T) or some default value.

    // Otherwise...
    Func<T> func = expression.Compile();
    return func();
}

Using the andand operator from Ruby as inspiration, you could create an extension method that acts as a null guard.

public static U AndAnd<T, U>(this T obj, Func<T, U> func)
{
    return obj == null ? default(U) : func(obj);
}

Your original code could then be rewritten as follows:

SomeSource.Where(srcItem => (srcItem.AndAnd(val => val.DataMembers["SomeText"]).AndAnd(val => val.Connection).AndAnd(val => val.ConnectedTo) as Type1).AndAnd(val => val.Handler).AndAnd(val => val.ForceInvocation));

Do be careful when returning non-boolean value types using this method - make sure you are familiar with the values returned by default(U).

create a separate func for it

This is the way to go. Do not be allergic to proper techniques. Methods you create are no more expensive (at runtime, and conceptually) than anonymous methods.

A while ago I wrote a project that mimics AndAnd that relies on DynamicProxy. It works fine, although I've not used it in prod. The only drawback is that it requires all of the members to be virtual or the returned types to be an interface so DynamicProxy can do its magic.

Check it here https://bitbucket.org/mamadero/andand/overview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!