Csharp學習Linq

来源:https://www.cnblogs.com/wenlong-4613615/p/18073134
-Advertisement-
Play Games

Linq的學習 這裡繼續使用之前文章創建的學生類,首先簡單介紹一下linq的使用。 Student.cs public class Student { public int Id { get; set; } public int ClassId { get; set; } public string ...


Linq的學習

這裡繼續使用之前文章創建的學生類,首先簡單介紹一下linq的使用。

Student.cs

 public class Student
 {
     public int Id { get; set; }
     public int ClassId { get; set; }

     public string Name { get; set; }

     public int Age { get; set; }

     public string Description { get; set; }

     public void Study()
     {
         Console.WriteLine($"{this.Id} {this.Name} 跟著老師學習 .Net開發");

     }

     public void StudyQt()
     {
         Console.WriteLine($"{this.Id} {this.Name} 跟著老師學習C++ Qt");
     }
 }

初始化學生數據

public class LinqPrinciple
{
    private List<Student> GetStudentsList()
    {
        List<Student> students = new List<Student>()
        { new Student() { Id = 1, ClassId = 1, Name = "張三", Age = 20, Description = "張三是一個好學生" },
             new Student() { Id = 2, ClassId = 1, Name = "李四", Age = 21, Description = "李四是一個好學生" },
             new Student() { Id = 3, ClassId = 2, Name = "王五", Age = 22, Description = "王五是一個好學生" },
             new Student() { Id = 4, ClassId = 2, Name = "趙六", Age = 23, Description = "趙六是一個好學生" },
             new Student() { Id = 5, ClassId = 3, Name = "孫七", Age = 24, Description = "孫七是一個好學生" },
             new Student() { Id = 6, ClassId = 3, Name = "周八", Age = 25, Description = "周八是一個好學生" },
              new Student() { Id = 7, ClassId = 1, Name = "綠春", Age = 30, Description = "張三是一個好學生" },
             new Student() { Id = 8, ClassId = 1, Name = "麻醉", Age = 35, Description = "李四是一個好學生" },
             new Student() { Id = 9, ClassId = 2, Name = "開天", Age = 26, Description = "王五是一個好學生" },
             new Student() { Id = 10, ClassId = 2, Name = "匹敵", Age = 22, Description = "趙六是一個好學生" },
             new Student() { Id = 11, ClassId = 3, Name = "獨輪車", Age = 23, Description = "孫七是一個好學生" },
             new Student() { Id = 12, ClassId = 3, Name = "火箭英", Age = 20, Description = "周八是一個好學生" }

        };
        return students;
    }
}

下麵寫幾個簡單的linq的語句,大概知道一下它的使用.


   public void  Show()
   {
       //獲取一下ClassID為3的學生們
       List<Student> students = GetStudentsList();
       List<Student> studentsId=students.Where(s => s.ClassId == 3).ToList();
       Console.WriteLine("********************************1*****************************");
       foreach (var student in studentsId)
       {
           Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
       }
       Console.WriteLine("********************************2*****************************");
       //獲取一下年紀大於24的學生們
       List<Student> studentsAge = students.Where(s => s.Age > 24).ToList();
       foreach (var student in studentsAge)
       {
           Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
       }
       Console.WriteLine("********************************3*****************************");
       //獲取一下年紀小於23同時ClassID為2的學生們
       List<Student> studentsAgeClassId = students.Where(s => s.Age < 23 && s.ClassId == 2).ToList();
       foreach (var student in studentsAgeClassId)
       {
           Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
       }
   }

linq的原理的探究

下麵嘗試探索一下這個linq的本質是什麼?

嘗試自己實現一下這3個需求代碼,如下

 List<Student> students = GetStudentsList();
 List<Student> studentsId=new List<Student>();
 foreach (var student in students)
 {
     if (student.ClassId == 3)
     {
         studentsId.Add(student);
     }
 }

 List<Student> studentsAge=new List<Student>();
 foreach (var student in students)
 {
     if (student.Age > 24)
     {
         studentsAge.Add(student);
     }
 }

 List<Student> studentsAgeClassId=new List<Student>();
 foreach (var student in students)
 {
     if (student.Age < 23 && student.ClassId == 2)
     {
         studentsAgeClassId.Add(student);
     }
 }

這上面的代碼有什麼問題?

大量的重覆代碼---最好是封裝一些,把重覆的代碼統一封裝;

這裡使用一個解決方案

封裝一個方法,將判斷的邏輯獨立到一個小方法中去.

        public static bool  IsOk01(Student student)
        {
            return student.ClassId == 3;
        }

        public static bool IsOk02(Student student)
        {
            return student.Age > 24;
        }

        public static bool IsOk03(Student student)
        {
            return student.Age < 23 && student.ClassId == 2;
        }
        public static List<Student> DragonWhere(List<Student> studentlist,Func<Student,bool> Func)
        {
            List<Student> students = new List<Student>();
            foreach (var student in studentlist)
            {
                if (Func(student))
                {
                    students.Add(student);
                }
            }
            return students;
        }

嘗試使用一下封裝的函數

List<Student> students = GetStudentsList();
List<Student> studentId= MethodExtension.DragonWhere(students, MethodExtension.IsOk01);

這裡還可以使用擴展方法和lambda表達式進一步的優化我們的代碼

      public static List<Student> DragonWhere(this List<Student> studentlist,Func<Student,bool> Func)
        {
            List<Student> students = new List<Student>();
            foreach (var student in studentlist)
            {
                if (Func(student))
                {
                    students.Add(student);
                }
            }
            return students;
        }

在調用的時候,

List<Student> students = GetStudentsList();
List<Student> studentsId = students.DragonWhere(s => s.ClassId == 3);

這裡就串聯上了我們之前學到的知識,最後為了支持多種數據類型,使用上泛型,最後我們就得到了最終封裝的方法.

 public static List<T> DragonWhere<T>(this List<T> studentlist,Func<T,bool> Func)
 {
     List<T> students = new List<T>();
     foreach (var student in studentlist)
     {
         if (Func(student))
         {
             students.Add(student);
         }
     }
     return students;
 }

這裡也要使用ilspy反編譯一下它們的實現是如何?

看起來跟我們自己實現的Where差不多的樣子.
img

再去看一下它的movenext函數.

img

這個就是一個yield return反彙編出來的狀態機的代碼。

linq常見的語句

 public void Show()
 {
     List<Student> studentList = this.GetStudentList(); 
     #region Linq 擴展方法&表達式
     {  
         var list = studentList.Where<Student>(s => s.Age < 30); //list裡面必然是符合要求的數據;
         foreach (var item in list)
         {
             Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
         }
     }
     {
         Console.WriteLine("********************");
         var list = from s in studentList
                    where s.Age < 30
                    select s;   //list裡面必然是符合要求的數據;

         foreach (var item in list)
         {
             Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
         }
     }
     #endregion

     #region linq to object Show
     {
         Console.WriteLine("********************");
         var list = studentList.Where<Student>(s => s.Age < 30)
                              .Select(s => new  //投影:可以做一些自由組裝+ new 一個匿名類,也可以new 具體類;
                              {
                                  IdName = s.Id + s.Name,
                                  ClassName = s.ClassId == 2 ? "高級班" : "其他班"
                              });
         foreach (var item in list)
         {
             Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName);
         }
     }
     {
         Console.WriteLine("********************");
         var list = from s in studentList
                    where s.Age < 30
                    select new
                    {
                        IdName = s.Id + s.Name,
                        ClassName = s.ClassId == 2 ? "高級班" : "其他班"
                    };

         foreach (var item in list)
         {
             Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName);
         }
     }
     {
         Console.WriteLine("********************");
         var list = studentList.Where<Student>(s => s.Age < 30)//條件過濾
                              .Select(s => new//投影
                              {
                                  Id = s.Id,
                                  ClassId = s.ClassId,
                                  IdName = s.Id + s.Name,
                                  ClassName = s.ClassId == 2 ? "高級班" : "其他班"
                              })
                              .OrderBy(s => s.Id)//排序 升序
                              .ThenBy(s => s.ClassName) //多重排序,可以多個欄位排序都生效
                              .OrderByDescending(s => s.ClassId)//倒排
                              .Skip(2)//跳過幾條  //必須要先排序
                              .Take(3)//獲取幾條 //必須要先排序
                              ;
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.ClassName}  Age={item.IdName}");
         }
     }
     {//group by·
         Console.WriteLine("********************");
         var list = from s in studentList
                    where s.Age < 30
                    group s by s.ClassId into sg
                    select new
                    {
                        key = sg.Key,
                        maxAge = sg.Max(t => t.Age)
                    };
         foreach (var item in list)
         {
             Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
         }
         //group by new {s.ClassId,s.Age}
         //group by new {A=s.ClassId>1}
     }
     {
         Console.WriteLine("********************");
         var list = studentList.GroupBy(s => s.ClassId).Select(sg => new
         {
             key = sg.Key,
             maxAge = sg.Max(t => t.Age)
         });
         foreach (var item in list)
         {
             Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
         }
     }
     {
         var list = studentList.GroupBy(s => s.ClassId);
         foreach (var date in list) ///實現了IEnumerable
         {
             Console.WriteLine(date.Key);

             foreach (var item in date)
             {
                 Console.WriteLine(item.Age);
             }

         }

     }
     List<Class> classList = new List<Class>()
         {
             new Class()
             {
                 Id=1,
                 ClassName="架構班"
             },
             new Class()
             {
                 Id=2,
                 ClassName="高級班"
             },
             new Class()
             {
                 Id=3,
                 ClassName="全棧班"
             },
         };
     {

         //Join 
         var list = from s in studentList
                    join c in classList on s.ClassId equals c.Id  //只能使用equals  不能使==
                    select new
                    {
                        Name = s.Name,
                        CalssName = c.ClassName
                    };
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
         }
     }
     {
         var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
         {
             Name = s.Name,
             CalssName = c.ClassName
         });
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
         }
     }
     {//左連接
         var list = from s in studentList
                    join c in classList on s.ClassId equals c.Id
                    into scList
                    from sc in scList.DefaultIfEmpty()//
                    select new
                    {
                        Name = s.Name,
                        CalssName = sc == null ? "無班級" : sc.ClassName//c變sc,為空則用
                    };
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
         }
         Console.WriteLine(list.Count());
     }
     {
         var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
         {
             Name = s.Name,
             CalssName = c.ClassName
         }).DefaultIfEmpty();//為空就沒有了
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
         }
         Console.WriteLine(list.Count());
     }
     {

         //左連接和右鏈接  就是鏈接對象交換一下即可;

     }
     #endregion
 }

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 就在昨晚,Java 22正式發佈!該版本提供了 12 項功能增強,其中包括 7 項預覽功能和 1 項孵化器功能。它們涵蓋了對 Java 語言、API、性能以及 JDK 中包含的工具的改進。 下麵就來一起學習一下該版本都更新了哪些新特性! Unnamed Variables & Patterns - ...
  • 基於Js和Java+MyBatis實現xlsx\xls文檔的導入下載、導出 背景: ​ 實現xlsx\xls文檔的導入、導出 ​ 導入效果: ​ 導出效果: 導出效果圖 1、導入、下載 1.1、前臺 <div style="margin-left: 15px"> <input type="file" ...
  • 本文介紹基於Python中ArcPy模塊,讀取Excel表格數據並生成帶有屬性表的矢量要素圖層,同時配置該圖層的坐標系的方法~ ...
  • 前言 還有個迭代器,基礎語法基本已經說完了,後面想到啥再補充,之後的教程會從以下方面來講: 基礎庫的使用,比如string、table等 基礎控制項的使用,比如listview、tab等 aardio和Python交互,比如給Python寫個界面 自帶的範常式序 我寫的一些小程式 當然,我的理解也是很 ...
  • 在.NET中Newtonsoft.Json(Json.NET)是我們常用來進行Json序列化與反序列化的庫。 而在使用中常會遇到反序列化Json時,遇到不規則的Json數據解構而拋出異常。 Newtonsoft.Json 支持序列化和反序列化過程中的錯誤處理。 允許您捕獲錯誤並選擇是處理它並繼續序列 ...
  • 作者引言 很高興啊,我們來到了第一篇,程式員的HelloWorld,快速開始RPC之游 快速入門 演示如何在幾分鐘內,使用IceRPC,構建和運行一個完整的客戶端-伺服器(C/S)應用程式. 必要條件: 只要電腦安裝 .NET 8 SDK 就行了. 來吧,開始你的RPC之旅 接下來,我們要一起構建一 ...
  • 攔截器Interceptors是一種可以在編譯時以聲明方式替換原有應用的方法。 這種替換是通過讓Interceptors聲明它攔截的調用的源位置來實現的。 您可以使用攔截器作為源生成器的一部分進行修改,而不是向現有源編譯添加代碼。 演示 使用 .NET 8 創建一個控制台應用程式。併在Propert ...
  • 概述:C#中整數除法返回整數,維護與低級語言相容性,提高性能。雖然精度有損,但可通過顯式浮點數轉換實現小數保留。 在C#中,整數除法返回整數而不是浮點數,這是為了保持與低級語言(如C和C++)的相容性,同時提高性能和降低複雜性。這種設計使得整數之間的除法操作更加高效,但可能導致精度喪失。 基礎功能: ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...