2

如果我有一长串对象,每个对象都有可能在“Linq where”子句中返回 null,例如

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

索引器可以返回 null,而“as”运算符可以返回 null。对象可能没有连接(即属性为空)。如果在任何地方遇到空值,我希望 where 子句为正在评估的项目返回“false”。相反,它会因空引用异常而中止。

在我看来,这将被设计为在单个 C# 表达式中表达。我不喜欢创建多行语句或为其创建单独的函数。是否有一些我缺少的空合并运算符的用途?

4

4 回答 4

2

使用 Ruby 中的andand运算符作为灵感,您可以创建一个充当空保护的扩展方法。

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

然后可以将您的原始代码重写如下:

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));

使用此方法返回非布尔值类型时要小心 - 确保您熟悉default(U).

于 2011-02-10T14:50:24.773 回答
2

您正在寻找 C# 中不存在的.?运算符(或者它是否是其中?.之一)(尽管根据 Eric Lippert 的说法,它是一个经常请求的功能)。

我唯一可能的建议是编写一个采用表达式并使用来检查任何空值的方法。但这会以性能为代价。无论如何,它可能看起来像:

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();
}
于 2011-02-10T14:28:30.583 回答
0

为它创建一个单独的函数

这是要走的路。不要对适当的技术过敏。您创建的方法(在运行时和概念上)并不比匿名方法更昂贵。

于 2011-02-10T14:21:18.440 回答
0

前段时间我写了一个模仿AndAnd的项目,它依赖于DynamicProxy。它工作正常,虽然我没有在产品中使用它。唯一的缺点是它要求所有成员都是虚拟的或返回的类型是接口,因此 DynamicProxy 可以发挥它的魔力。

在这里查看 https://bitbucket.org/mamadero/andand/overview

于 2012-06-20T22:27:35.797 回答