C#3.0メモ1
主にLINQまわり1
3.0での省略記法について
データ型は型推論により決定される。
その為、省略して書かれていても型はしっかりと決まっている。
クラス定義の省略記法
public class Parson { public String Name { get; set; } public String Sex { get; set; } public String Belong { get; set; } } //この書き方は、ParsonがNewされた後に各項目へ値をセットする。 //その為、ReadOnlyなメンバなどにはセットできない。 Parson[] parsons = { new Parson(){Name = "山田太郎", Sex="男", Belong="営業"}, new Parson(){Name = "勝山次郎", Sex="男", Belong="営業"}, new Parson(){Name = "山中真奈美", Sex="女", Belong="技術"}, new Parson(){Name = "としこ", Sex="女", Belong="秘書"}, new Parson(){Name = "越中銀次郎", Sex="男", Belong="広報"}, new Parson(){Name = "大鳥昭信", Sex="男", Belong="社長"} };
LINQでの反復処理
Enumerableクラスで定義されているメソッド・IEnumerableクラスの拡張メソッドで、ごにょごにょすることが多い。
シンプルなクエリ
//select句には、クエリを実行したときに生成される値の型を指定します。 //省略した場合は、範囲変数と同じデータ型のシーケンスが返される。 //qのデータ型はIEnumerable<int> var q = from x in Enumerable.Range(1, 10) select x; foreach (var rec in q) Console.WriteLine(rec.ToString());
クエリ同士の結合
//商品分類 private class ItemKind { public int KindId { get; set; } public String KindName { get; set; } } //商品 private class Item { public int ItemId { get; set; } public int KindId { get; set; } public String ItemName { get; set; } public int ItemPrice { get; set; } } //クエリ実行 private class JoinQueryTest { private ItemKind[] kinds; private List<Item>items = new List<Item>(); private Random rmd; public JoinQueryTest() { rmd = new Random(); kinds = new ItemKind[] { new ItemKind() { KindId = 1, KindName = "分類1" }, new ItemKind() { KindId = 2, KindName = "分類2" }, new ItemKind() { KindId = 3, KindName = "分類3" }, new ItemKind() { KindId = 4, KindName = "分類4" }, }; for (int i = 0; i < 10000; i++) { items.Add(new Item(){ItemId = i + 1 , ItemName = "アイテム" + i.ToString() , ItemPrice = 10000 - i , KindId=rmd.Next(1,4) }); } } public void DoTasukigakeQuery() { var sw = new System.Diagnostics.Stopwatch(); //下記クエリのようなJoinしないたすきがけは非常に遅いので使用しないこと。 sw.Start(); var q1 = from x in kinds from y in items where x.KindId == y.KindId && x.KindId == 2 select new { Name = y.ItemName, Kind = x.KindName }; sw.Stop(); Console.WriteLine("Query1 Define Time:{0}", sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); StringBuilder sb = new StringBuilder(); foreach (var rec in q1) sb.Append("Name:" + rec.Name + " Kind:" + rec.Kind.ToString()); sw.Stop(); Console.WriteLine("Query1 ResultOutputInfo Count:{0} Time:{1}", q1.Count(), sw.ElapsedMilliseconds); sw.Reset(); } public void DoJoinQuery() { var sw = new System.Diagnostics.Stopwatch(); sw.Start(); var q2 = from x in items join y in kinds on x.KindId equals y.KindId where x.KindId == 2 select new { Name = x.ItemName, Kind = y.KindName }; sw.Stop(); Console.WriteLine("Query2 Define Time:{0}", sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); StringBuilder sb = new StringBuilder(); foreach (var rec in q2) sb.Append("Name:" + rec.Name + " Kind:" + rec.Kind.ToString()); sw.Stop(); Console.WriteLine("Query2 ResultOutputInfo Count:{0} Time:{1}", q2.Count(), sw.ElapsedMilliseconds); sw.Reset(); } } //[実行結果] //1回目 //Query1 Define Time:0 //Query1 ResultOutputInfo Count:3308 Time:14 //Query2 Define Time:2 //Query2 ResultOutputInfo Count:3308 Time:16 //2回目 //Query1 Define Time:0 //Query1 ResultOutputInfo Count:3354 Time:10 //Query2 Define Time:0 //Query2 ResultOutputInfo Count:3354 Time:2 //3回目 //Query1 Define Time:0 //Query1 ResultOutputInfo Count:3392 Time:8 //Query2 Define Time:0 //Query2 ResultOutputInfo Count:3392 Time:3 //4回目 //Query1 Define Time:0 //Query1 ResultOutputInfo Count:3325 Time:27 //Query2 Define Time:0 //Query2 ResultOutputInfo Count:3325 Time:3 //5回目 //Query1 Define Time:0 //Query1 ResultOutputInfo Count:3329 Time:14 //Query2 Define Time:0 //Query2 ResultOutputInfo Count:3329 Time:4