67

標準のlinqキーワードまたはラムダ式での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);

これらは、2番目の例がもう少し簡潔であるのと非常に似ていますが、=>が何をしているのかわからない場合は、おそらく表現力が低下します。

簡潔なコードを書く以外に、LINQ構文とは対照的に拡張メソッドを使用することには他の利点がありますか?

4

7 に答える 7

36

正直なところ、Funcs と Actions を使い始めると状況に応じて変わることがあります。次の 3 つの関数を使用しているとします。

  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;

ご覧のように、最初のものはユーザー名を取得するためにラムバ式を置き換え、2 つ目は ID が 10 より小さいかどうかをチェックするために使用されるラムバ式を置き換えます。

注: これはばかげた例ですが、機能します。

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

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

この例では、拡張メソッドが Func をフルに活用できるため、2 番目の式は少し冗長ですが、Linq 式は boolean を返す Func ではなく Boolean を探すだけなので、それはできません。ただし、これは式言語を使用した方がよい場合があります。単なるユーザー以上のものを受け取るメソッドがすでにあるとします。

  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)

ラムダ式がなければ、本当にそのメソッドを呼び出すことはできません。そこで、元のメソッド呼び出しに基づいて Func を作成するメソッドを作成する必要があります。

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

そして、それを接続します:

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

ご覧のとおり、クエリ アプローチを使用する方が簡単な場合もあります。

于 2008-11-12T15:32:47.717 に答える
25

LINQ 拡張メソッド (メソッド ベースのクエリ) を使用する利点の 1 つは、カスタム拡張メソッドを定義でき、それでも問題なく読み取れることです。

一方、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");

私の意見では、メソッドベースのクエリを使用する後者は、カスタム拡張メソッドがある場合に読みやすくなります。

于 2008-11-11T01:16:14.577 に答える
14

併用せず、どちらかを選んで使い続けるのがいいと思います。

主に個人的な好みですが、クエリ構文 (理解メソッド) では、前述のようにすべての演算子が使用できるわけではありません。

拡張メソッドの構文は、私のコードの残りの部分とより一致していると思います。私はSQLでSQLを行います。また、拡張メソッドを使用してすべてを相互に追加するだけで、式を簡単に作成できます。

ちょうど私の2セント。

私はまだコメントを書くことができないので、ここでプログラミングツールの答えにコメントしたいと思います: なぜ最後の例のために全く新しいメソッドを作るのですか?? あなたはただ使うことができません:

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

于 2010-12-01T07:09:13.587 に答える
6

それらは同じようにコンパイルされ、同等です。個人的には、ほとんどの場合、ラムダ(拡張)メソッドを好みます。SQLに対してLINQを実行している場合、またはSQLをエミュレートしようとしている場合にのみ、ステートメント(標準)を使用します。ラムダメソッドはコードの方が流れやすいのに対し、ステートメントは視覚的に気が散ることがわかります。

于 2008-11-11T01:04:10.467 に答える
4

FirstOrDefault() など、同等のクエリ構文を持たない Linq メソッドを使用する場合は、拡張メソッド構文を使用します。

于 2008-11-12T14:30:19.760 に答える
-2

私は、それが実際にクエリである場合、つまりオンデマンドで評価される遅延式である場合に、クエリ構文を使用するのが好きです。

通常のメソッド呼び出し (メソッド構文またはラムダ構文) のように見えるメソッドは、十分に怠惰に見えないため、慣例として使用します。たとえば、

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

2 つの通話スタイルをよりよく区別するのに役立ちます。もちろん、とにかくメソッド構文を使わざるを得ない状況もあるので、私の慣習はあまり説得力がありません。

于 2014-03-06T17:22:33.783 に答える