扩展方法语法与查询语法

发布于 2024-07-08 12:30:48 字数 475 浏览 14 评论 0原文

我正在尝试了解是否有合适的时机使用标准 linq 关键字或带有 lambda 表达式的 linq 扩展方法。 他们似乎做同样的事情,只是写法不同。 这纯粹是风格问题吗?

var query = from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p;

// or with extension methods:
var query = Products
    .Where(p => p.Name.Contains("foo"))
    .OrderBy(p => p.Name);

它们与第二个示例非常相似,第二个示例更简洁,但如果您不知道 => 是什么,则可能缺乏表达力。 是在做。

除了编写简洁的代码之外,使用扩展方法相对于 LINQ 语法还有其他优点吗?

I'm trying to get a handle on if there's a good time to use standard linq keywords or linq extension methods with lambda expressions. They seems to do the same thing, just are written differently. Is it purely a matter of style?

var query = from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p;

// or with extension methods:
var query = Products
    .Where(p => p.Name.Contains("foo"))
    .OrderBy(p => p.Name);

They're very similar with the second example being a bit more terse, but perhaps less expressive if you don't know what the => is doing.

Other than writing terse code, are there other advantages to using the extension methods as opposed to the LINQ syntax?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

满身野味 2024-07-15 12:30:48

老实说,有时一旦您开始使用 Funcs 和 Actions,情况可能会有所不同。 假设您正在使用这三个函数:

  Func<DataClasses.User, String> userName = user => user.UserName;
  Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
  Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;

如您所见,第一个函数替换了 lamdba 表达式来获取用户名,第二个函数替​​换了用于检查 ID 是否低于 10 的 lamdba 表达式,让我们面对现实吧,第三个函数应该现在就很容易理解了。

注意:这是一个愚蠢的例子,但它确实有效。

  var userList = 
    from user in userList
    where userIDOverTen(user)
    select userName;

  var otherList =
    userList
    .Where(IDIsBelowNumber)
    .Select(userName)

在此示例中,第二个稍微不那么冗长,因为扩展方法可以充分利用 Func,但 Linq 表达式不能,因为它只是查找布尔值而不是返回布尔值的 Func 然而,这就是使用表达式语言可能更好的地方。 假设您已经有了一个不仅仅接受用户的方法:

  private Boolean IDIsBelowNumber(DataClasses.User user, 
          Int32 someNumber, Boolean doSomething)
  {
    return user.UserID < someNumber;
  }

注意:doSomething 之所以存在,是因为 where 扩展方法可以接受接受用户和整数并返回布尔值的方法。 这个例子有点烦人。

现在,如果您查看 Linq 查询:

  var completeList =
     from user in userList
     where IDIsBelowNumber(user, 10, true)
     select userName;

您已经很擅长了。 现在是扩展方法:

  var otherList =
    userList
    .Where(IDIsBelowNumber????)
    .Select(userName)

如果没有 lambda 表达式,我真的无法调用该方法。 所以现在我要做的是创建一个方法,该方法根据原始方法调用创建一个 Func 。

   private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
   {
      return user => IDIsBelowNumber(user, number, true);
   }

然后将其插入:

  var otherList =
     userList
     .Where(IDIsBelowNumberFunc(10))
     .Select(userName)

所以您可以看到,有时使用查询方法可能会更容易。

Honestly, sometimes it can be situational once you start using Funcs and Actions. Say you are using these three funcs:

  Func<DataClasses.User, String> userName = user => user.UserName;
  Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
  Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;

As you can see the first one replaces the lamdba expression to get the user name, the second replaces a lamdba expression used to check if the ID is lower than 10, and let's face it, the third should be pretty easy to understand now.

NOTE: This is a silly example but it works.

  var userList = 
    from user in userList
    where userIDOverTen(user)
    select userName;

Versus

  var otherList =
    userList
    .Where(IDIsBelowNumber)
    .Select(userName)

In this example, the second is a little less verbose since the extension method can make full use of the Func, but he Linq expression can't since it is look just for a Boolean rather than a Func that returns boolean. However, this is where it might be better to use the expression language. Say you already had a method that takes in more than just a user:

  private Boolean IDIsBelowNumber(DataClasses.User user, 
          Int32 someNumber, Boolean doSomething)
  {
    return user.UserID < someNumber;
  }

Note: doSomething is just there because of the where extension method being ok with a method that takes in a user and integer and returns boolean. Kind of annoying for this example.

Now if you look at the Linq query:

  var completeList =
     from user in userList
     where IDIsBelowNumber(user, 10, true)
     select userName;

You're good for it. Now the Extension Method:

  var otherList =
    userList
    .Where(IDIsBelowNumber????)
    .Select(userName)

Without a lambda expression, I really can't call that method. So now what I have to do is create a method that creates a Func based off the original method call.

   private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
   {
      return user => IDIsBelowNumber(user, number, true);
   }

And then plug it in:

  var otherList =
     userList
     .Where(IDIsBelowNumberFunc(10))
     .Select(userName)

So you can see, sometimes it may just be easier to use the query approach at times.

臻嫒无言 2024-07-15 12:30:48

使用 LINQ 扩展方法(基于方法的查询)的一个优点是您可以定义自定义扩展方法,并且它仍然可以正常读取。

另一方面,当使用 LINQ查询表达式时,自定义扩展方法不在关键字列表中。 与其他关键字混合在一起看起来会有点奇怪。

示例

我正在使用名为 Into 的自定义扩展方法,它只接受一个字符串:

带有查询的示例

var query = (from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p).Into("MyTable");

带有扩展方法的

var query = Products
                   .Where(p => p.Name.Contains("foo"))
                   .OrderBy(p => p.Name)
                   .Into("MyTable");

示例在我看来,后者使用基于方法的查询,当您有自定义扩展方法时,读起来会更好。

One advantage to using LINQ extension methods (method-based queries) is that you can define custom extension methods and it will still read fine.

On the other hand, when using a LINQ query expression, the custom extension method is not in the keywords list. It will look a bit strange mixed with the other keywords.

Example

I am using a custom extension method called Into which just takes a string:

Example with query

var query = (from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p).Into("MyTable");

Example with extension methods

var query = Products
                   .Where(p => p.Name.Contains("foo"))
                   .OrderBy(p => p.Name)
                   .Into("MyTable");

In my opinion the latter, using a method-based query, reads better when you have custom extension methods.

最终幸福 2024-07-15 12:30:48

我认为最好不要一起使用它们,选择一个并坚持使用。

主要是个人喜好,但在查询语法(理解方法)中,并非所有运算符都可用,如前面所说。

我发现扩展方法语法更符合我的代码的其余部分。 我用 SQL 执行 SQL。 只需使用扩展方法将所有内容相互叠加即可构建表达式也非常容易。

只是我的两分钱。

由于我还不能发表评论,我想在这里对编程工具的答案发表一下:
为什么要为最后一个例子制定一个全新的方法? 你不能只使用:


.Where(用户 => IDIsBelowNumber(用户, 10, true))

I think it's a good idea not to use them together and choose one and stick with it.

Mostly it's personal taste, but in the query syntax (Comprehension method) not all operators are available as was said before.

I find the Extension Methods syntax more in line with the rest of my code. I do my SQL in SQL. It's also very easy to build your expression just by adding everything on top of eachother with the extension methods.

Just my two cents.

As I cannot make comments yet I want to make one here to the answer of Programming Tool:
Why make a whole new method for the last example?? Can't you just use:


.Where(user => IDIsBelowNumber(user, 10, true))

心如狂蝶 2024-07-15 12:30:48

它们编译相同,并且是等效的。 就个人而言,对于大多数事情,我更喜欢 lambda(扩展)方法,仅当我执行 LINQ to SQL 或尝试模拟 SQL 时才使用语句(标准)。 我发现 lambda 方法在代码中的流动性更好,而语句在视觉上会分散注意力。

They compile the same, and are equivalent. Personally, I prefer the lambda (extension) methods for most things, only using the statements (standard) if I'm doing LINQ to SQL or otherwise trying to emulate SQL. I find that the lambda methods flow better with code, whereas the statements are visually distracting.

十雾 2024-07-15 12:30:48

当我使用没有等效查询语法的 Linq 方法(例如 FirstOrDefault() 或其他类似方法)时,我更喜欢扩展方法语法。

I prefer the extension method syntax when I use Linq methods that have no query syntax equivalent, such as FirstOrDefault() or others like that.

帅气称霸 2024-07-15 12:30:48

时,扩展方法语法更简洁且更具可读性

  • 当不通过 Select 进行转换
  • 。 没有中间变量。
  • 没有通过 SelectMany 的笛卡尔积。

查询语法有很多优点,但最后必须写一个 select p 是一个糟糕的举动。 作为较大方法链的一部分时,它的噪音也更大。 在以下示例中,查询语法比较简洁:

var result =
  from a in tableA
  from b in tableB
  where a.SomeValue == b.SomeValue
  select Compose(a, b) as p
  orderby p.rank
  select p.ToArray();

The extension-method syntax is terser and more readable when

  • No transformation via Select.
  • No intermediate variables.
  • No cartesian products via SelectMany.

The query syntax has many advantages, but having to write a select p in the end is a bad move. It's also more noisy when as part of a larger method chain. In the following example, the query syntax is terser:

var result =
  from a in tableA
  from b in tableB
  where a.SomeValue == b.SomeValue
  select Compose(a, b) as p
  orderby p.rank
  select p.ToArray();
芸娘子的小脾气 2024-07-15 12:30:48

我喜欢在真正的查询时使用查询语法,即按需计算的惰性表达式。

看起来像常规方法调用(方法语法或 lambda 语法)的方法看起来不够懒惰,所以我将其用作约定。 例如,

var query = from p in Products
            where p.Name.Contains("foo")
            orderby p.Name
            select p;

var result = query.ToList(); //extension method syntax

如果它不是查询,我喜欢流畅的风格,在我看来,它与其他急切执行的调用一致。

var nonQuery = Products.Where(p => p.Name.Contains("foo"))
                       .OrderBy(p => p.Name)
                       .ToList();

它帮助我更好地区分两种通话方式。 当然,在某些情况下您将被迫使用方法语法,因此我的约定不够引人注目。

I like to use the query syntax when its really a query, ie a lazy expression which evaluates on demand.

A method that looks like regular method calls (method syntax or the lambda syntax) doesn't look lazy enough, so I use that as a convention. For eg,

var query = from p in Products
            where p.Name.Contains("foo")
            orderby p.Name
            select p;

var result = query.ToList(); //extension method syntax

If it's a not a query, I like the fluent style which looks to me consistent with other eagerly executing calls.

var nonQuery = Products.Where(p => p.Name.Contains("foo"))
                       .OrderBy(p => p.Name)
                       .ToList();

It helps me to differentiate the two styles of calls better. Of course there are situations where you will be forced to use method syntax anyway, so my convention is not very compelling enough.

你如我软肋 2024-07-15 12:30:48

扩展方法/lynda 表达式的优点之一是提供了额外的运算符,例如 Skip 和 Take。 例如,如果您正在创建分页方法,则可以轻松实现跳过前 10 条记录并获取后 10 条记录。

One advantage of extension methods/lynda expressions is the additional operators that is offered like Skip and Take. For example, if you are creating a pagination method, being able to skip the first 10 records and take the next 10 is easy to implement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文