読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET 絡みのメモを公開しています。

Linq入門記-01 (遅延実行、例外処理, try, catch)

C# Linq


C# 4.0もそろそろ足音が聞こえてくる今日この頃。
今更ながら、Linq入門し始めました。w
(最近、技術の進化が速すぎるように感じます・・・・)


すごく便利なのは分かっているのですが、バリバリ使っていますかというと
実務では全然使っていないです。(やっぱりいきなり最新技術は中々みんな使いません)


でも、C# 4.0が出る前に勉強しておかないとまた新しい概念が出てきます。orz


てことで、Linqの使い方ですが、今回はいきなり例外処理の話とします。
何故かというと、結構間違えている人多いみたいなのです。
実務で利用する場合もそうでない場合もエラー処理は必須です。
なので、この点をしっかり押さえておかないといけません。


Linqは遅延実行を行います。つまり

var query = from   x in ListA
            select x;

foreach(var x in query) {
    ...
}

という処理を実行した際、実際にクエリが実行されるのは
foreachにてループ処理が行われるタイミングです。
query変数を定義している段階では処理は行われていません。
(query変数を定義した後すぐにToList()などを呼んでいる場合は別です。)


で、当然エラー処理を入れますが

IEnumerable<X> query = null;
try {
    query = from   x in ListA
            select x;
} catch {
    エラー処理
}

foreach(var x in query) {
    ...
}

は間違いです。遅延実行が行われるので
実際に例外が発生するのは、foreach側の処理の方となります。
(変数queryを構築している部分は単に定義を行っているみたいなものです)


なので、

var query = from   x in ListA
            select x;

try {
    
    foreach(var x in query) {
        ...
    }
} catch {
    エラー処理
}

としなくてはなりません。


以下、サンプルです。

#region LinqSamples-01
    public class LinqSamples01 : IExecutable {
        
        class Person {
            public string Id{ get; set; }
            public string Name{ get; set; }
            public AddressInfo Address{ get; set;}
        }

        class AddressInfo {
            public string PostCode{ get; set; }
            public string Prefecture{ get; set; }
            public string Municipality{ get; set; }
            public string HouseNumber{ get; set; }
            public string Tel{ get; set; }
        }

        IEnumerable<Person> CreateSampleData() {

            return new Person[]{
                 new Person{ 
                         Id="00001"
                        ,Name="gsf_zero1"
                        ,Address=new AddressInfo{
                                         PostCode="999-8888"
                                        ,Prefecture="東京都"
                                        ,Municipality="どこか1"
                                        ,HouseNumber="番地1"
                                        ,Tel="090-xxxx-xxxx"
                        }
                 }
                ,new Person{ 
                         Id="00002"
                        ,Name="gsf_zero2"
                        ,Address=new AddressInfo{
                                         PostCode="888-7777"
                                        ,Prefecture="京都府"
                                        ,Municipality="どこか2"
                                        ,HouseNumber="番地2"
                                        ,Tel="080-xxxx-xxxx"
                        }
                }
                ,new Person{ 
                         Id="00003"
                        ,Name="gsf_zero3"
                        ,Address=new AddressInfo{
                                         PostCode="777-6666"
                                        ,Prefecture="北海道"
                                        ,Municipality="どこか3"
                                        ,HouseNumber="番地3"
                                        ,Tel="070-xxxx-xxxx"
                        }
                }
                ,new Person{ 
                         Id="0000x"
                        ,Name="gsf_zero3"
                        ,Address=new AddressInfo{
                                         PostCode="777-6666"
                                        ,Prefecture="北海道"
                                        ,Municipality="どこか3"
                                        ,HouseNumber="番地3"
                                        ,Tel="070-xxxx-xxxx"
                        }
                }
            };
        }

        public void Execute() {

            IEnumerable<Person> persons = CreateSampleData();

            var query = from   person in persons
                        where  int.Parse(person.Id) >= 2
                        select person;

            try {

                foreach(Person person in query) {
                    Console.WriteLine("{0},{1}", person.Id, person.Name);
                }

            } catch(Exception ex) {
                Console.WriteLine("クエリ実行時にエラーが発生: {0}", ex.Message);
            }
        }

    }
#endregion


次から、一つずつクエリキーワードを勉強していく予定です。
頑張ってLinqマスターします。



================================
過去の記事については、以下のページからご参照下さい。