質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

Q&A

解決済

1回答

8059閲覧

C# LINQのクエリ構文とメソッド構文

teraotailnosuke

総合スコア52

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

0グッド

0クリップ

投稿2016/12/28 12:29

編集2016/12/29 10:48

解決したい課題

なんとなくですが、LINQのクエリ構文は嫌われているような気がするのですが、気のせいですか?
何か特別な理由があるのでしょうか?

メソッド構文じゃないと書けないケースがあるからメソッド構文だけ覚えとけ、ということでしょうか?

個人的に、メソッドチェーンを改行でぶった切るのはとても気持ち悪いです。
ピリオドの前後はつながっていてほしい。あと括弧が多くなりがちなのもちょっと・・・
クエリ式の方が見やすいと思うのですが。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

C#はたまに書く程度なので機会は少ないですが、LINQを書く時はメソッドチェーンでばかり書いています。正直に言うとクエリ式は調べながらであれば読める程度であまり覚えてないです。何で自分がそうしているのか、その理由を考えました。

###クエリ式を避ける5つの理由

####覚えるのが面倒
クエリ式はSQLと似ていますが、似ているだけで違います。結局新たに覚える必要があります。使える場所が.NET言語だけであり、かといってC#とF#とVB.NETで書き方が完全に同じというとそういうわけでもありません。使いどころが限られているような物に対して、積極的に学ぼうとは思えないという事があります。しかし、メソッドチェーンやラムダ式は他にも必要になるので、覚えないという選択肢がありません。

####SQLっぽいのが嫌
SQL使いの人はSQL構文こそが至高だと思う人がいるようですが、私個人は、SQL構文は見やすいとは思っていません。

理由は構造が平坦だからです。どれが命令でどれが変数なのか、どれが引数なのかという事が一目でわかるのは重要です。SQL文にはそれがないため、命令となるキーワードは大文字、テーブル名などは小文字にして区別する場合が多いような気がします。しかしクエリ式のキーワードは小文字のみです。そして、ローカル変数は慣習より小文字の場合が多く、ぱっと見の区別が付きません。

適切な箇所で改行し、IDEでシンタックスカラー付けされていれば問題ないと思うかも知れませんが、そうしないと無理という時点で、構文自体に欠陥があると思っています。

####異なる文法が混ざる事への違和感
F#とVB.NETはまだいいですが、C#では違和感があります。C#は名前の通りC言語風の文法を採用しています。そのため、SQL風の文法とは全く相容れません。一つの言語に二つの文法が混ざると言うことは、区別はしやすくなるかも知れませんが、とても違和感を感じます。プログラミングのコード上にSQL文をべた書きしているぐらいの嫌な感じがしてきます。

####使えない物がある
C#のクエリ式にはLINQの全ての演算子が含まれていません。結局メソッドチェーンと組み合わせなくてはいけなくなるときがあります。それなら最初から全てメソッドチェーンで書いた方がいいとなってしまいます。

####メソッドチェーン+ラムダ式の書き方になれている
他の言語ですと、LINQのようなリスト処理はメソッドチェーンとラムダ式で書きます。むしろ、そっちの方に慣れています。

リスト処理の書き方は概ね四種類あると思います。下記の書き方の例は、整数の配列listから奇数のみ取り出して、それを二乗したものの総和を求めるというものです。例で使用している言語は()で後ろに付けています。

  1. リスト内包表記

書き方: sum [x * x|x <- list, odd x] (Haskell)
リストを選択写像しながら新たなリストを作る方法です。全体の囲みがリストリテラルと同じ物([]が多い)を使っており、全体がリストリテラルのように扱えるという利点があります。できることには限界があるため、他と組み合わせて使います。
主な言語: Haskell、Python、CoffeeScript
2. 連続関数適用
書き方: sum (map (\x -> x * x) (filter odd list)) (Haskell)
書き方(関数結合): sum . map (\x -> x * x) . filter odd $ list (Haskell)
あるリストに対し、関数を一つ一つ適用していく方法です。新たなリストの作成に1.リスト内包表記も併用する場合が多いです。括弧のお化けになりやすいですが、実際は関数結合などを使うことで、それほど括弧を必要としない場合が多いです。
主な言語: Lisp、Haskell、Python
3. パイプライン
書き方: list |> List.filter (fun x -> x % 2 <> 0) |> List.map (fun x -> x * x) |> List.sum (F#)
2.の考えでは右から左に読む必要があり、普段の文章の読み方と逆方向になるため、少しつらい場合があります。そこで考えられたのがパイプラインです。左から右にデータが流れる形であるため、自然に読むことができる方式です。
主な言語: F#、Elixir、LiveScript
4. メソッドチェーン
書き方: list.filter(x => x % 2 != 0).map(x => x * x).sum (Scala)
これまでのは非オブジェクト指向での関数型言語で考えられてきた方法です。そこにオブジェクト指向を加えるとメッソド呼び出しを主体にする必要があるため、メソッドを次々繋ぐという方法になります。パイプラインに近い考えで構築できます。
主な言語: Scala、Ruby

これら2〜4の方法は、それ自体が独立した関数やメソッドを次々と適用していくという物で、それらの関数やメソッドは別途定義ができる物なので再利用なども可能です。しかし、クエリ式やSQLはこのどれでもなく、全体で一つの式を形成しており、分解不可能です。これらの考え方に慣れている人から見ると、とても使いにくく思えてしまいます。

もし、他言語と一番近いのは何かというとリスト内包表記です。しかし、クエリ式はリスト内包表記ほど柔軟で無く、リスト内包表記ほどコンパクトでは無く、リスト内包表記ほどみやすくなく、リスト内包表記ほど簡単ではありません。

クエリ式: (from x in list where x % 2 != 0 select x * x).Sum() (C#)
メソッドチェーン: list.Where(x => x %2 != 0).Select(x => x * x).Sum() (C#)

そして、結局()で囲んでしまって、訳がわからない物なっていると思います。


あくまで個人の感想です。C#は使いこなしていると言うほど使っていないため、参考程度に思っていただければと思います。

投稿2016/12/29 12:12

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問