Linq 查询扩展

Linq Query Expanding

我有一个名为 Products 的字符串数组,我正在研究匿名方法 (Lambda Exprs.) 和 Linq。 所以我先写了;

var resultSet1 = from p in products 
                 where p.StartsWith("M") 
                 orderby p descending  
                 select p;

然后我用 Lambda 表达式扩展它;

var resultSet2 = products
                 .Where(p => p.StartsWith("M"))
                 .OrderByDescending(p => p)
                 .Select(p => p);

然后我用匿名方法扩展它;

var resultSet3 = products
                .Where(delegate(string p) { return p.StartsWith("M"); })
                .OrderByDescending(delegate(string p) { return p; })
                .Select(delegate(string p) { return p; });

然后我用 Manual Methods 和 Func<> Delegates 扩展它;

Func<string, bool> filterFunc = new Func<string, bool>(Filter);
Func<string, string> orderAndSelectFunc = new Func<string, string>(OrderAndSelect);
var resultSet4 = products.Where(filterFunc).OrderByDescending(orderAndSelectFunc).Select(orderAndSelectFunc);

static bool Filter(string p) { return p.StartsWith("M"); }
static string OrderAndSelect(string p) { return p; }

然后我卡住了。所以我的问题是;我可以通过用普通委托替换 Func<> 委托来进一步扩展它吗?或者类似的东西?

Then I expand it with Lambda Expressions ...

表达式.Select(p => p)在流畅的语法中是不必要的。你可以删除它。

Then I expand it with Anonymous Methods

在这种情况下,lambda 只是匿名方法的简化版本。

Can I expand this a bit more with replacing Func<> delegate with normal delegates?

是的,你可以。在 class 中使用与 Func<> 匹配的签名定义静态方法,并使用它们代替匿名函数或委托。您可以使用方法组语法来制作委托来缩短代码:

private static bool StartsWithM(string s) {
    return s.StartsWith("M");
}
private static string PassThrough(string s) {
    return s;
}
...
var resultSet4 = products
            .Where(StartsWithM)
            .OrderByDescending(PassThrough)
            .Select(PassThrough); // <<== Again, this can be removed

不确定您希望通过 "de-sugaring" 原件实现什么,但您可以删除多余的功能

var resultSet4 = products.Where(Filter).OrderByDescending(OrderAndSelect).Select(orderAndSelect);

static bool Filter(string p) { return p.StartsWith("M"); }
static string OrderAndSelect(string p) { return p; }

在扩展方面,我认为这涵盖了最扩展的情况(除非您将 Order 和 Select 分开)。

也许解释一下为什么你想这样做会有所帮助吗?