西西軟件下載最安全的下載網(wǎng)站、值得信賴的軟件下載站!

首頁編程開發(fā)C#.NET → SelectMany替代二重foreach循環(huán)、用Linq替代C# 2.0的寫法

SelectMany替代二重foreach循環(huán)、用Linq替代C# 2.0的寫法

相關(guān)軟件相關(guān)文章發(fā)表評論 來源:西西整理時(shí)間:2012/11/27 8:48:27字體大。A-A+

作者:西西點(diǎn)擊:0次評論:0次標(biāo)簽: Linq

  • 類型:數(shù)據(jù)庫類大小:1.7M語言:英文 評分:5.0
  • 標(biāo)簽:
立即下載

學(xué)習(xí)Linq其實(shí)已經(jīng)很久了,但是一直沒有使用的習(xí)慣,故水平也始終沒有提高。近來刻意強(qiáng)迫自己用Linq來替代C# 2.0的一些寫法。這里有一些心得和各位分享一下。

首先看下面兩個類的定義:

  class Student
    {
        public int Score { get; set; }

        public Student(int score)
        {
            this.Score = score;
        }
    }

    class Teacher
    {
        public string Name { get; set; }

        public List<Student> Students;

        public Teacher(string order,List<Student> students)
        {
            this.Name = order;

            this.Students = students;
        }
    }

用以上兩個類構(gòu)建集合如下:

          List<Teacher> teachers = new List<Teacher>
            {
                new Teacher("a",new List<Student>{ new Student(100),new Student(90),new Student(30) }),
                new Teacher("b",new List<Student>{ new Student(100),new Student(90),new Student(60) }),
                new Teacher("c",new List<Student>{ new Student(100),new Student(90),new Student(40) }),
                new Teacher("d",new List<Student>{ new Student(100),new Student(90),new Student(60) }),
                new Teacher("e",new List<Student>{ new Student(100),new Student(90),new Student(50) }),
                new Teacher("f",new List<Student>{ new Student(100),new Student(90),new Student(60) }),
                new Teacher("g",new List<Student>{ new Student(100),new Student(90),new Student(60) })
            };

這里有7個老師,每個人有3個學(xué)生,總共21一個學(xué)生里又有3個倒霉蛋沒考及格……我們想要獲得這3個倒霉蛋的集合。C# 2.0的代碼如下:

            List<Student> studentList = new List<Student>();
            foreach (var t in teachers)
            {
                foreach (var s in t.Students)
                {
                    if (s.Score < 60)
                    {
                        studentList.Add(s);
                    }
                }
            }

已經(jīng)寫了N多這樣的二重foreach,寫的都要吐了,簡直恨不得做成代碼段。因?yàn)樗芯幊陶Z言都能這么寫,有人覺得C#簡單,可好學(xué)了,抓到就寫,民工專用,抄襲Java,微軟出品,必屬垃圾,明天正午12點(diǎn)之前就會被淘汰……
        反正我覺得C# 3.0之后是越來越難,越來越復(fù)雜。難道是年紀(jì)大了智商堪憂……那既然要反駁,今天我們就換個C# 3.0的新寫法。首先是查詢表達(dá)式的寫法:

            var list1 = from t in teachers
                        from s in t.Students
                        where s.Score < 60
                        select s;

是不是感覺好多了,就跟寫SQL一樣順暢。而且一目了然。也許習(xí)慣于OOXX的.NET程序員不那么喜歡SQL的語法,那還可以試試Lamda表達(dá)式的寫法:

  var list2 = teachers.SelectMany(t => t.Students).Where(s => s.Score < 60);

嗯?怎么只有一行,這是不是太欺負(fù)人了,到時(shí)候公司數(shù)代碼行數(shù)算工錢的時(shí)候怎么辦……嗯……這種公司你還是離了吧……
寫到這里我不禁感慨起SelectMany的偉大了,太好用了。其實(shí)我們剛才只是用了最簡單的SelectMany也就是這個方法:

public static IEnumerable<TResult> SelectMany<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TResult>> selector
)

這個用于IEnumerable<T>的擴(kuò)展方法接受一個Func委托,根據(jù)你的需要再返回另一個IEnumerable<T>,配合Where真是秒殺二重foreach啊。
有時(shí)候我們需要輸出更復(fù)雜的結(jié)果集,比如校長想知道教出這3個考不及格的倒霉蛋的,到底是哪幾個更加倒霉的老師。那我們就要用到SelectMany的另一個重載方法了:

public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TCollection>> collectionSelector,
    Func<TSource, TCollection, TResult> resultSelector
)

第一眼看上去有點(diǎn)暈,重點(diǎn)是第一個Func委托的返回值IEnumerable<TCollection>,會遍歷作為第二個Func委托的參數(shù)TCollection傳遞,供你構(gòu)建所需要的投影集合。這里給出一個例子,下面的代碼選出了門下有不及格學(xué)生的倒霉蛋老師+門生的分?jǐn)?shù):

            var list3 = teachers.SelectMany(
                t => t.Students,
                (t, s) => new { t.Name, s.Score })
                .Where(n => n.Score < 60);

在這里,校長大人得到的集合,不僅包含了所有不及格的分?jǐn)?shù),同時(shí)還對應(yīng)了該分?jǐn)?shù)學(xué)生的教師姓名。慘啊……

    相關(guān)評論

    閱讀本文后您有什么感想? 已有人給出評價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    發(fā)表評論 查看所有評論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)