国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C#基礎(chǔ)--Lambda和LINQ

這篇具有很好參考價(jià)值的文章主要介紹了C#基礎(chǔ)--Lambda和LINQ。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

C#基礎(chǔ)–Lambda 和 LINQ

一、Lambda 的前世今生

在.NetFramewok的不同版本都有不同的樣子;在.NetCore下也都是支持的;

1.1 .Netframework1.0/1.1時(shí)代

public delegate void NoReturnWithPara(int x, string y);

NoReturnWithPara method = new NoReturnWithPara(Study);
method.Invoke(123, "Richard");

private void Study(int id, string name)
{
    Console.WriteLine($"{id} {name} 學(xué)習(xí).Net高級(jí)班");
}

1.2 .NetFramework2.0

匿名方法 增加了一個(gè)delegate關(guān)鍵字, 可以訪問到除了參數(shù)以外的局部變量

public delegate void NoReturnWithPara(int x, string y);

int i =0;
NoReturnWithPara method = new NoReturnWithPara(delegate (int id, string name)
{
	Console.WriteLine($"{id} {name} 學(xué)習(xí).Net高級(jí)班");
	Console.WriteLine(i);	//可以訪問到除了參數(shù)以外的局部變量 i
});
method.Invoke(123, "Richard");

1.3 .NetFramework3.0 前期

去掉了delegate關(guān)鍵字,添加了一個(gè)=> goes to

public delegate void NoReturnWithPara(int x, string y);

int i =0;
NoReturnWithPara method = new NoReturnWithPara((int id, string name) =>
{
	Console.WriteLine($"{id} {name} 學(xué)習(xí).Net高級(jí)班");
	Console.WriteLine(i);
});
method.Invoke(123, "Richard");

1.4 .NetFramework3.0 后期

去掉了匿名方法后的參數(shù)類型,編譯器自動(dòng)推斷來的/編譯器提供的便捷功能(語法糖)

public delegate void NoReturnWithPara(int x, string y);

int i =0;
NoReturnWithPara method = new NoReturnWithPara((id, name) =>  //編譯器自動(dòng)推斷來的/編譯器提供的便捷功能(語法糖)
{
	Console.WriteLine($"{id} {name} 學(xué)習(xí).Net高級(jí)班");
	Console.WriteLine(i);
});
method.Invoke(123, "Richard");

如果匿名方法體中只有一行代碼,可以省略方法體的大括號(hào):

public delegate void NoReturnWithPara(int x, string y);

NoReturnWithPara method = new NoReturnWithPara((id, name) => Console.WriteLine($"{id} {name} 學(xué)習(xí).Net高級(jí)班"));
method.Invoke(123, "Richard");
public delegate void NoReturnWithPara(int x, string y);

NoReturnWithPara method = (id, name) => Console.WriteLine($"{id} {name} 學(xué)習(xí).Net高級(jí)班");
method.Invoke(123, "Richard");

如果只有一個(gè)參數(shù)的時(shí)候:

Action<string> method = sn => Console.WriteLine($"歡迎{sn} 來到.Net高級(jí)班進(jìn)階學(xué)習(xí)");
method.Invoke("牧羊人");

如果有返回值? 如果lambda表達(dá)式中只有一行代碼,且有返回值,可以省略return;

Func<string> func0 = () => { return "黃大仙" };

//如果有返回值? 如果lambda表達(dá)式中只有一行代碼,且有返回值,可以省略 `大括號(hào)` + `return`;
Func<string> func = () => "黃大仙";
Func<int, string> func1 = i => i.ToString();

大家覺得Lambda表達(dá)式本質(zhì)是什么?

多播委托中可以把Lambda表達(dá)式+=,但是不能把Lambda表達(dá)式-=。因?yàn)長ambda表達(dá)式其實(shí)是一個(gè)方法,不同的lambda表達(dá)式就是不同的方法。

Lambda的本質(zhì)是一個(gè)方法。

語法糖:編譯器提供的便捷功能

二、LINQ

初始化數(shù)據(jù)

List<Student> studentList = new List<Student>()
{
    new Student() { Id=1, Name="趙亮", ClassId=2, Age=35 },
    new Student() { Id=2, Name="再努力一點(diǎn)", ClassId=2, Age=23 },
    new Student() { Id=3, Name="王炸", ClassId=2, Age=27 },
    new Student() { Id=4, Name="瘋子科學(xué)家", ClassId=2, Age=26 },
    new Student() { Id=5, Name="滅", ClassId=2, Age=25 },
    new Student() { Id=6, Name="黑騎士", ClassId=2, Age=24 },
    new Student() { Id=7, Name="故鄉(xiāng)的風(fēng)", ClassId=2, Age=21 },
    new Student() { Id=8, Name="晴天", ClassId=2, Age=22 }
};

2.1 Linq 擴(kuò)展方法&表達(dá)式

var list = studentList.Where<Student>(s => s.Age < 30); //list里面必然是符合要求的數(shù)據(jù);
var list = from s in studentList
			where s.Age < 30
			select s;   //list里面必然是符合要求的數(shù)據(jù);

以上兩種都是LINQ。

2.2 linq to object

Linq – Linq to object:就是針對IEnumerable類型數(shù)據(jù)

? 1. IEnumerable 類型數(shù)據(jù):可以理解為內(nèi)存中的數(shù)據(jù);其實(shí)就是把不變的邏輯封裝起來,把可變的邏輯封裝成委托來傳遞;

? 2. IQueryable 類型數(shù)據(jù):可以理解成內(nèi)存數(shù)據(jù)—來自于數(shù)據(jù)庫的數(shù)據(jù);

延伸:

Linq to Sql:就是把打開數(shù)據(jù)庫連接,查詢數(shù)據(jù)(不變的的邏輯),把sql 的拼裝(可變的邏輯)

Linq to Xml:把數(shù)據(jù)解析這類動(dòng)作封裝起來(不變的邏輯), 把數(shù)據(jù)篩選條件封裝成委托來傳遞(可變的邏輯)

Linq to Redis:把固定的邏輯封裝起來,把不變的邏輯封裝成委托傳遞

Linq to Cache:…

Linq to JSON:…

Linq to Everything:…

IQueryable 和 IEnumerable 存在本質(zhì)的區(qū)別:

  1. 使用IQueryable 查詢
List<Student> studentList = this.GetStudentList();

var query = studentList.AsQueryable();
query.Where(a => a.Age < 30);

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
  1. 使用 IEnumerable 查詢
List<Student> studentList = this.GetStudentList();

var query = studentList.AsEnumerable();
query.Where(a => a.Age < 30);

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

IEnumerable 傳遞的是一個(gè)委托,而 IQueryable 傳遞的是一個(gè)表達(dá)式目錄樹(數(shù)據(jù)結(jié)構(gòu))

現(xiàn)在大家覺得Linq 是什么?

Linq 是一種封裝思想,對于用戶來說,就把不需要關(guān)心內(nèi)部怎么實(shí)現(xiàn),只需要Linq一下即可;微軟之前很推崇這種思想,只讓開發(fā)者關(guān)注自己的核心邏輯,不需要關(guān)注內(nèi)部邏輯,徹底的把開發(fā)者變成編程小白;如果大家有經(jīng)驗(yàn)的話,你會(huì)發(fā)現(xiàn)像Asp .Net MVC就屬于傻瓜式開發(fā),成套的;我們不用去關(guān)心原理就可以直接上手。

但是現(xiàn)在又變了,現(xiàn)在有更高的要求,像是Linq to JSON、Linq to Redis等并沒有人來封裝這些。如果大家有興趣,可以去嘗試封裝一下。

2.3 基本查詢

var list = studentList.Where<Student>(s => s.Age < 30)
                                     .Select(s => new
                                     {
                                         IdName = s.Id + s.Name,
                                         ClassName = s.ClassId == 2 ? "高級(jí)班" : "其他班"
                                     });
var list = from s in studentList
            where s.Age < 30
            select new
			{
                IdName = s.Id + s.Name,
                ClassName = s.ClassId == 2 ? "高級(jí)班" : "其他班"
            };

Select 方法:

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

**備注:**使用 studentList.Where(s => s.Age < 30) 查詢并返回?cái)?shù)據(jù)后,實(shí)際內(nèi)容還是一個(gè) IEnumerable 的數(shù)據(jù)。但是接著再使用了Select 做投影的話,里面創(chuàng)建了一個(gè)匿名對象,返回的也是一個(gè)匿名對象。

2.4 分頁

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 ? "高級(jí)班" : "其他班"
                                     })
                                     .OrderBy(s => s.Id)//排序
                                     .ThenBy(s=>s.ClassName)    //多重排序,可以多個(gè)字段排序都生效
                                     .OrderByDescending(s => s.ClassId)//倒排
                                     .Skip(2)//跳過幾條
                                     .Take(3)//獲取幾條
                                     ;

性能怎樣?=> 本質(zhì)其實(shí)都是循環(huán);

2.5 分組

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)
            };
var list = studentList.Where(a=>a.Age<30)
    					.GroupBy(c => c.ClassId)
    					.Select(sg => new
                		{
                            key = sg.Key,
                            maxAge = sg.Max(t => t.Age)
                        });

2.6 內(nèi)連接 – inner join

var list = from s in studentList
            join c in classList on s.ClassId equals c.Id
            select new
            {
                Name = s.Name,
                CalssName = c.ClassName
            };
var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
                {
                    Name = s.Name,
                    CalssName = c.ClassName
                });

2.7 左連接 – left join

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 ? "無班級(jí)" : sc.ClassName//c變sc,為空則用
           };
var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
                {
                    Name = s.Name,
                    CalssName = c.ClassName
                }).DefaultIfEmpty();

三、自定義封裝

3.1 針對一個(gè)具體類的封裝

/// <summary>
/// 如果換個(gè)條件怎么辦?
/// 使用委托:委托可以把方法當(dāng)做參數(shù)傳遞;方法其實(shí)是邏輯,委托可以把邏輯當(dāng)做參數(shù)傳遞;
/// 委托:應(yīng)該是返回值為bool的委托,參數(shù)是一個(gè)Student
/// </summary>
/// <param name="resource"></param>
/// <returns></returns>
public static List<Student> RichardWhere(this List<Student> resource, Func<Student, bool> func)
{
    List<Student> list = new List<Student>();
    foreach (var item in resource)
    {
        //if (item.Name.Length > 2) //條件的判斷其實(shí)就是邏輯---動(dòng)作 //唯一的區(qū)別就在與中間這里的條件不一樣;
        if (func.Invoke(item))
        {
            list.Add(item);
        }
    }
    return list;
}

3.2 通用–泛型封裝

/// <summary>
/// 這就是Linq中where的本質(zhì);
/// 1. 是把固定不變的邏輯,封裝起來,把可變的邏輯封裝成委托來傳遞
/// 就可以讓開發(fā)者只需要關(guān)注自己的核心業(yè)務(wù),其他別的都以LINQ封裝
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="resource"></param>
/// <param name="func"></param>
/// <returns></returns>
public static List<T> RichardWhere<T>(this List<T> resource, Func<T, bool> func) where T:class
{
    List<T> list = new List<T>();
    foreach (var item in resource)
    {
        //if (item.Name.Length > 2) //條件的判斷其實(shí)就是邏輯---動(dòng)作 //唯一的區(qū)別就在與中間這里的條件不一樣;
        if (func.Invoke(item))
        {
            list.Add(item);
        }
    }
    return list;
}
/// <summary>
/// 有什么好處?
/// 通過接口來擴(kuò)展,只要實(shí)現(xiàn)了這個(gè)接口的,都可以使用當(dāng)前這個(gè)擴(kuò)展方法
/// 相比而言:自然擴(kuò)展抽象要好一些,擴(kuò)展性更好
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="resource"></param>
/// <param name="func"></param>
/// <returns></returns>

public static IEnumerable<T> RichardWhereEnumerable<T>(this IEnumerable<T> resource, Func<T, bool> func) where T : class
{
    List<T> list = new List<T>();
    foreach (var item in resource)
    {
        //if (item.Name.Length > 2) //條件的判斷其實(shí)就是邏輯---動(dòng)作 //唯一的區(qū)別就在與中間這里的條件不一樣;
        if (func.Invoke(item))
        {
            list.Add(item);
        }
    }
    return list;
}

3.3 實(shí)際運(yùn)用

如果是學(xué)生類的實(shí)現(xiàn)對象的話,3.1 和3.2都是的話下面代碼一樣,無需任何修改

var list1 = MethodExtension.RichardWhere(studentList, item => item.Age < 30);
var list2 = studentList.RichardWhere(item => item.Age < 30);

var list1 = MethodExtension.RichardWhere(studentList, item => item.Name.Length > 2);
var list2 = studentList.RichardWhere(item => item.Name.Length > 2);

var list1 = MethodExtension.RichardWhere(studentList, item => item.Id > 1
                                         && item.Name != null
                                         && item.ClassId == 1
                                         && item.Age > 20);
//循環(huán)完畢以后,list里面必然是符合要求的數(shù)據(jù);
var list2 = studentList.RichardWhere<Student>(item => item.Id > 1
                                              && item.Name != null
                                              && item.ClassId == 1
                                              && item.Age > 20);

四、yield 使用

/// <summary>
/// yield` 必須和 IEnumerable<T> 配合使用,可以做到按需獲取
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="resource"></param>
/// <param name="func"></param>
/// <returns></returns>
public static IEnumerable<T> RichardWhereIterator<T>(this IEnumerable<T> resource, Func<T, bool> func) where T : class
{
    foreach (var item in resource)
    {
        if (func.Invoke(item))
        {
            yield return item;
        }
    }
    return list;
}

var list3 = studentList.RichardWhereIterator(item => item.Age < 30);
foreach (var item in list3)
{
    Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
}

yield 必須和 IEnumerable<T> 配合使用,可以做到按需獲??;如果返回值換成 List<T> 就會(huì)產(chǎn)生報(bào)錯(cuò)

按需獲?。?/strong> var list3 = studentList.RichardWhereIterator(item => item.Age < 30); 執(zhí)行完之后,并沒有實(shí)質(zhì)性執(zhí)行到 RichardWhereIterator 方法內(nèi)部,直到 foreach (var item in list3) 的時(shí)候,才執(zhí)行到方法體內(nèi),而且是循環(huán)一次就到 RichardWhereIterator 獲取一條數(shù)據(jù)。

C#基礎(chǔ)--Lambda和LINQ,C# .Net,c#,linq

使用yield 的使用,編譯器會(huì)生成一個(gè)泛型的,會(huì)有個(gè)迭代狀態(tài)機(jī) [IteratorStateMachine] (屬于特性)文章來源地址http://www.zghlxwxcb.cn/news/detail-581834.html

到了這里,關(guān)于C#基礎(chǔ)--Lambda和LINQ的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C#基礎(chǔ):利用LINQ進(jìn)行復(fù)雜排序

    請你寫出linq對表格排序, CODE=3排前面 ,其余按照 CODE降序 排序,CODE一樣再按照 字母升序 排序 ID CODE VALUE A0001 1 A A0002 1 B A0003 1 C A0004 2 D A0005 2 E A0006 2 F A0007 3 G A0008 3 H A0009 3 I A0010 4 J 若再加大難度,ID=A0005的排第一,然后CODE=3排前面,其余按照CODE降序排序,再按照字母升序排

    2024年01月18日
    瀏覽(18)
  • 【C# 基礎(chǔ)精講】LINQ to XML查詢

    【C# 基礎(chǔ)精講】LINQ to XML查詢

    LINQ to XML 是 C# 中用于查詢和操作 XML 數(shù)據(jù)的強(qiáng)大工具。它允許您使用 LINQ 查詢語法對 XML 文檔進(jìn)行查詢、過濾、投影等操作,從而更加方便地處理 XML 數(shù)據(jù)。本文將詳細(xì)介紹 LINQ to XML 的基本概念、常見操作以及示例,幫助您了解如何在 C# 中使用 LINQ to XML 進(jìn)行 XML 數(shù)據(jù)的查詢和

    2024年02月12日
    瀏覽(50)
  • 【C# 基礎(chǔ)精講】LINQ to Objects查詢

    【C# 基礎(chǔ)精講】LINQ to Objects查詢

    LINQ to Objects是LINQ技術(shù)在C#中的一種應(yīng)用,它專門用于對內(nèi)存中的對象集合進(jìn)行查詢和操作。通過使用LINQ to Objects,您可以使用統(tǒng)一的語法來查詢、過濾、排序、分組等操作各種.NET對象。本文將詳細(xì)介紹LINQ to Objects的基本概念、常見的操作和示例,以幫助您更好地理解如何在

    2024年02月11日
    瀏覽(18)
  • WPF上位機(jī)9——Lambda和Linq

    WPF上位機(jī)9——Lambda和Linq

    2024年02月14日
    瀏覽(21)
  • AI面試官:LINQ和Lambda表達(dá)式(一)

    當(dāng)面試官面對C#中關(guān)于LINQ和Lambda表達(dá)式的面試題時(shí),通常會(huì)涉及這兩個(gè)主題的基本概念、用法、實(shí)際應(yīng)用以及與其他相關(guān)技術(shù)的對比等。以下是一些可能的面試題目,附帶簡要解答和相關(guān)案例和代碼: 解答:LINQ(Language Integrated Query)是一種在C#編程語言中集成的查詢技術(shù),

    2024年02月15日
    瀏覽(21)
  • AI面試官:LINQ和Lambda表達(dá)式(三)

    當(dāng)面試官面對C#中關(guān)于LINQ和Lambda表達(dá)式的面試題時(shí),通常會(huì)涉及這兩個(gè)主題的基本概念、用法、實(shí)際應(yīng)用以及與其他相關(guān)技術(shù)的對比等。以下是一些可能的面試題目,附帶簡要解答和相關(guān)案例和代碼: 解答:延遲執(zhí)行是指LINQ查詢在遍歷結(jié)果之前不會(huì)立即執(zhí)行,而是在實(shí)際需

    2024年02月16日
    瀏覽(18)
  • AI面試官:LINQ和Lambda表達(dá)式(二)

    當(dāng)面試官面對C#中關(guān)于LINQ和Lambda表達(dá)式的面試題時(shí),通常會(huì)涉及這兩個(gè)主題的基本概念、用法、實(shí)際應(yīng)用以及與其他相關(guān)技術(shù)的對比等。以下是一些可能的面試題目,附帶簡要解答和相關(guān)案例和代碼: 解答:Lambda表達(dá)式的閉包是指它可以訪問其周圍范圍內(nèi)的變量,即使這些變

    2024年02月16日
    瀏覽(14)
  • C# Linq 學(xué)會(huì)使用,學(xué)會(huì)自己編寫Linq

    C# Linq 學(xué)會(huì)使用,學(xué)會(huì)自己編寫Linq

    Linq我暫時(shí)理解為,一種內(nèi)置的非常方便的數(shù)據(jù)查詢的工具 我們先學(xué)習(xí)它的使用 //數(shù)據(jù)類 //新建了一個(gè)List數(shù)據(jù),用來測試數(shù)據(jù)查詢? //現(xiàn)在定義一個(gè)需求,需要查出 id2 的數(shù)據(jù) 引用Linq的命名空間 ?引用命名空間之后,我們的list對象,擁有了一個(gè)擴(kuò)展方法,Where (擴(kuò)展方法,在之前的博客

    2024年02月06日
    瀏覽(29)
  • C#中的LINQ

    一:什么是LINQ LINQ代表語言集成查詢,是.net框架的擴(kuò)展,它允許我們用SQL查詢數(shù)據(jù)庫的方式來查詢數(shù)據(jù)的集合 二:LINQ延遲查詢的特性 延遲查詢是指查詢操作并不是在定義的時(shí)候執(zhí)行,而是在遍歷集合中的數(shù)據(jù)時(shí)才執(zhí)行 因?yàn)樽鳛閥ield迭代器的主體,只有使用foreach遍歷執(zhí)行到

    2023年04月09日
    瀏覽(21)
  • C# Linq 詳解二

    C# Linq 詳解二

    目錄 概述 七、OrderBy? 八、OrderByDescending 九、Skip 十、Take 十一、Any 十二、All C# Linq 文檔(一) 1.Where,2.Select,3.GroupBy,4.First / FirstOrDefault,5.Last / LastOrDefault C# Linq 文檔(二) 1.OrderBy ,2.OrderByDescending,3.Skip,4.Take,5.Any,6.All C# Linq 文檔(三) 1.Sum / Min / Max / Average,2.Dist

    2024年02月16日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包