欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

帶你一文了解C#中的LINQ

 更新時(shí)間:2021年12月13日 10:37:51   作者:RyzenAdorer  
c#提供的ling查詢(xún)極大的遍歷了集合的查詢(xún)過(guò)程,且使用簡(jiǎn)單方便,非常的有用,下面這篇文章主要給大家介紹了關(guān)于C#中LINQ的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

本文主要的是泛談LINQ是啥?以及常見(jiàn)的用法大綱如下:

  • LINQ的那些根基
  • LINQ的一些基本用法

LINQ的根基

IEnumerable和IEnumerator

為啥能夠被foreach?

實(shí)際上,能夠被foreach的對(duì)象,一定是實(shí)現(xiàn)了帶有返回值的IEnumerator的GetEnumerator()方法的接口,而.NET內(nèi)置的該接口則是IEnumerable,一般指的是IEnumerable泛型接口,讓我們來(lái)看看IEnumerator接口有啥成員:

   public interface IEnumerator
   {
       object Current
       {
           get;
       }

       bool MoveNext();

       void Reset();
   }
  • Current:集合當(dāng)前的對(duì)象
  • MoveNext:是否能夠移動(dòng)到下一次
  • Reset

因此,實(shí)際上我們進(jìn)行foreach的時(shí)候,等價(jià)于:

var animals = new List<string>() { "Cat", "Dog", "Pig" };

foreach (var animla in animals)
{
    Console.WriteLine(animla);
}
Console.WriteLine("-----------");

var enumerator = animals.GetEnumerator();
while (enumerator.MoveNext())
{
    Console.WriteLine(enumerator.Current);
}

輸出結(jié)果:

Cat

Dog

Pig

-----------

Cat

Dog

Pig

而能被LINQ的對(duì)象就是一個(gè)實(shí)現(xiàn)了IEnumerable的可被枚舉的集合

LINQ的基本用法

擴(kuò)展方法在LINQ的應(yīng)用:LINQ的流式語(yǔ)法

LINQ的方法一般都是通過(guò)擴(kuò)展方法了擴(kuò)展的,就如最常用的幾個(gè),Where,Any,例如,我實(shí)現(xiàn)了一個(gè)跟Where功能類(lèi)似的簡(jiǎn)化版:

 public static class MyListExtension
{
    public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> enumable, Func<T, bool> func)
    {
        foreach (var item in enumable)
        {
            if (func(item))
            {
                yield return item;
            }
        }
    }
}

其實(shí)為啥會(huì)提到用擴(kuò)展方法呢?就是因?yàn)長(zhǎng)INQ就是為了簡(jiǎn)單的能夠處理復(fù)雜集合的數(shù)據(jù),那么擴(kuò)展方法就能夠?qū)崿F(xiàn)較為簡(jiǎn)單的鏈?zhǔn)讲樵?xún),例如:

var result= animals.MyWhere(t => t is "Cat" or "Dog").Select(t=>t.ToUpper()).ToList();

result.ForEach(t =>Console.WriteLine(t));

輸出結(jié)果:

CAT

DOG

LINQ的查詢(xún)表達(dá)式:LINQ的查詢(xún)語(yǔ)法

假如上述的例子有LINQ的查詢(xún)表達(dá)式來(lái)編寫(xiě),則寫(xiě)法是這樣:

var result = (from t in animals
              where t is "Cat" or "Dog"
              select t.ToUpper()).ToList();

result.ForEach(t => Console.WriteLine(t));

輸出結(jié)果也是一樣的:

CAT

DOG

LINQ的延遲執(zhí)行:IQueryable

首先我們來(lái)看看IQueryable的接口定義:

    public interface IQueryable : IEnumerable
    {

        Type ElementType
        {
            get;
        }

 
        Expression Expression
        {
            get;
        }

        IQueryProvider Provider
        {
            get;
        }
    }

我們可以看到實(shí)際上IQueryable是繼承了IEnumerable,因此同樣具備其特性,然后主要看其三個(gè)屬性:

  • ElementType:集合的類(lèi)型
  • Expression:表達(dá)式樹(shù),這是延遲執(zhí)行的重點(diǎn),下面我們會(huì)一窺究竟
  • IQueryProvider:IQueryable創(chuàng)建表達(dá)式樹(shù)和執(zhí)行的部分
    public interface IQueryProvider
    {
  
        IQueryable CreateQuery(Expression expression);

  
        IQueryable<TElement> CreateQuery<TElement>(Expression expression);


        object? Execute(Expression expression);


        TResult Execute<TResult>(Expression expression);
    }

我們先來(lái)看段代碼:

var result1 = (from t in animals
                where (t.Equals( "Cat") || t.Equals("Dog"))
                select t.ToUpper()).AsQueryable();
Console.WriteLine($"Expression:{ result1.Expression.ToString()}");
Console.WriteLine($"ExpressionType:{result1.Expression.GetType()}");
foreach (var item in result1)
{
    Console.WriteLine(item);
}

Console.WriteLine("---------------");
var result2 = from t in result1
              where  t.Contains("CAT")
              select t;
Console.WriteLine($"Expression:{ result2.Expression.ToString()}");
Console.WriteLine($"ExpressionType:{result2.Expression.GetType()}");
foreach (var item in result2)
{
    Console.WriteLine(item);
}

輸出如下:

Expression:System.Linq.Enumerable+WhereSelectListIterator`2[System.String,System.String]

ExpressionType:System.Linq.Expressions.ConstantExpression

CAT

DOG

---------------

Expression:System.Linq.Enumerable+WhereSelectListIterator`2[System.String,System.String].Where(t => t.Contains("CAT"))

ExpressionType:System.Linq.Expressions.MethodCallExpression2

CAT

我們從輸出可以證明,實(shí)際上在返回result1和result2,就是通過(guò)IQueryProvider不斷地在拼接表達(dá)式樹(shù),而最后通過(guò)foreach或者ToList等操作的時(shí)候,則才是真正調(diào)用Execute方法執(zhí)行當(dāng)前的IQueryable里的那個(gè)表達(dá)式樹(shù)屬性Expression,而像LINQ To Sql或者是EFCore等需要IQueryable這種解釋型的就是去實(shí)現(xiàn)了IQueryProvider里面的方法

附:將內(nèi)存中對(duì)象轉(zhuǎn)換為 XML

LINQ 查詢(xún)可以輕松地在內(nèi)存中數(shù)據(jù)結(jié)構(gòu)、SQL 數(shù)據(jù)庫(kù)、ADO.NET 數(shù)據(jù)集和 XML 流或文檔之間轉(zhuǎn)換數(shù)據(jù)。 以下示例將內(nèi)存中數(shù)據(jù)結(jié)構(gòu)中的對(duì)象轉(zhuǎn)換為 XML 元素。

class XMLTransform
{
    static void Main()
    {
        // Create the data source by using a collection initializer.
        // The Student class was defined previously in this topic.
        List<Student> students = new List<Student>()
        {
            new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81, 60}},
            new Student {First="Claire", Last="O'Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}},
            new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}},
        };

        // Create the query.
        var studentsToXML = new XElement("Root",
            from student in students
            let scores = string.Join(",", student.Scores)
            select new XElement("student",
                       new XElement("First", student.First),
                       new XElement("Last", student.Last),
                       new XElement("Scores", scores)
                    ) // end "student"
                ); // end "Root"

        // Execute the query.
        Console.WriteLine(studentsToXML);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}

此代碼生成以下 XML 輸出:

<Root>  
  <student>  
    <First>Svetlana</First>  
    <Last>Omelchenko</Last>  
    <Scores>97,92,81,60</Scores>  
  </student>  
  <student>  
    <First>Claire</First>  
    <Last>O'Donnell</Last>  
    <Scores>75,84,91,39</Scores>  
  </student>  
  <student>  
    <First>Sven</First>  
    <Last>Mortensen</Last>  
    <Scores>88,94,65,91</Scores>  
  </student>  
</Root>

參考

《C#7.0核心技術(shù)指南》

源碼

BlogCodeSample/LinqSample at main · ZhengDaoWang/BlogCodeSample

總結(jié)

到此這篇關(guān)于C#中LINQ的文章就介紹到這了,更多相關(guān)C#的LINQ內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論