C#如何重复使用适用于具有相同类型的不同属性的LINQ表达式

16

我有一个类,其中包含多个 int 属性:

class Foo
{
    string bar {get; set;}
    int a {get; set;}
    int b {get; set;}    
    int c {get; set;}
}

我有一个LINQ表达式,希望能在List<Foo>上使用。我希望能够使用这个表达式通过查看任何三个属性来过滤/选择列表。例如,如果我按a进行过滤:

return listOfFoo.Where(f => f.a >= 0).OrderBy(f => f.a).Take(5).Select(f => f.bar);

然而,我希望能够对f.af.bf.c中的任何一个进行过滤。不想重复输入3次LINQ表达式,希望有一种方法可以通过参数指定要过滤的a、b或c,并返回结果。

有没有在C#中实现这个功能的办法?目前没有明显的解决思路,但是感觉应该是可行的。


这是纯LINQ,还是你要转到其他地方,比如Entity Framework?如果是纯LINQ,你可以通过反射来解决它。 - AndrewP
@AndrewP 我不熟悉Entity Framework,所以我可能不会使用它。只要能达到相同的预期效果,它甚至不需要是一个LINQ解决方案。 - nhinkle
1
你有查看过 Dynamic Linq 吗? - Pratik Gaikwad
1个回答

29
IEnumerable<string> TakeBarWherePositive(IEnumerable<Foo> sequenceOfFoo, Func<Foo, int> intSelector) {
  return sequenceOfFoo
            .Where(f => intSelector(f) >= 0)
            .OrderBy(intSelector)
            .Take(5)
            .Select(f => f.bar);
}

那么你就可以称之为

var a = TakeBarWherePositive(listOfFoo, f => f.a);
var b = TakeBarWherePositive(listOfFoo, f => f.b);

哇!这个可以工作...但我仍然不确定我完全理解了。你能再解释一下Func<Foo, int>吗?我熟悉使用Func,但从未见过像那样将类类型传递给它。Func<a, b>的这种用法是否基本上相当于“类型为b的属性在类型a中”?是否有MSDN页面或其他描述此用法的内容? - nhinkle
5
Func<Foo, int>表示“一个接受类型为Foo的值并返回类型为int的值的函数。”在您给出的示例中,f => f.af => f.b都是Func<Foo, int>类型。您还可以执行更奇异的操作,例如f => f.a + 1000,或者像f => 1000这样愚蠢的操作--所有这些都是TakeBarWherePositive的有效参数。 - Nick
@nhinkle,这只是由Microsoft预先编写的简单委托,因此您不需要每次需要传递一些方法时都声明自己的委托。 - Deadzone
当然,现在有意义了。谢谢@Nick - 回想起来那似乎很明显,但我从未想过以那种方式传递它。 - nhinkle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接