zoukankan      html  css  js  c++  java
  • C# LINQ需求实现演化

      Linq是C#3.0引入的,在C#2.0实现从集合中过滤符合条件的记录实现方式。

      假设有一个Book类,以及一个Book类的集合,现在需要从集合中查找出单价大于50的Book。

      1、固定查询字段的实现方式:

      Book.cs类:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LINQTest
    {
        public class Book
        {
            public string Title { get; set; }
    
            public decimal Price { get; set; }
    
            public string Author { get; set; }
    
            public string ISBN { get; set; }
        }
    }

      Help.cs类:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LINQTest
    {
        public class Helper
        {
            public static IList<Book> SearchBookByPrice()
            {
                IList<Book> books = new List<Book> {
                    new Book{Title="Book1", Author="Author1", ISBN="ISBN1", Price=30},
                    new Book{Title="Book2", Author="Author2", ISBN="ISBN2", Price=40},
                    new Book{Title="Book3", Author="Author3", ISBN="ISBN3", Price=50},
                    new Book{Title="Book4", Author="Author4", ISBN="ISBN4", Price=60}
                };
    
                IList<Book> results = new List<Book>();
                foreach (Book book in books)
                {
                    if (book.Price >= 50)
                    {
                        results.Add(book);
                    }
                }
    
                return results;
            }
        }
    }

      Program.cs类:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LINQTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                foreach (Book book in Helper.SearchBookByPrice())
                {
                    Console.WriteLine("{0}-{1}", book.Title, book.Price);
                }
            }
        }
    }

      上面的代码中实现了根据Price查询集合中大于50的记录。但是当需求有变动,需要根据Title来查询时,则上面的实现方法需要另外进行编写按Title查询的方法。

      2、不固定查询字段的实现方式

      查询条件最后返回的只是true或false,在新定义的方法中,只要if语句中返回为true的记录,添加到集合中即可,而不需要去知道具体是什么查询条件。

      Helper.cs类:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LINQTest
    {
        public class Helper
        {
            public delegate bool Condition(Book book);
    
            public bool ConditionTitle(Book book)
            {
                return book.Title == "Book2";
            }
    
            public bool ConditionPrice(Book book)
            {
                return book.Price >= 50;
            }
    
            public static IList<Book> SearchBookByCondition(Condition condition)
            {
                IList<Book> books = new List<Book> {
                    new Book { Title = "Book1", Author = "Author1", ISBN = "ISBN1", Price = 30 },
                    new Book { Title = "Book2", Author = "Author2", ISBN = "ISBN2", Price = 40 },
                    new Book { Title = "Book3", Author = "Author3", ISBN = "ISBN3", Price = 50 },
                    new Book { Title = "Book4", Author = "Author4", ISBN = "ISBN4", Price = 60 }
                };
                
    
                IList<Book> results = new List<Book>();
    
                foreach (Book book in books)
                {
                    if (condition(book))
                    {
                        results.Add(book);
                    }
                }
    
                return results;
            }
        }
    }

      Program.cs类:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LINQTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                //Helper.Condition condition = new Helper.Condition(new Helper().ConditionTitle);
                Helper.Condition condition = new Helper().ConditionTitle;
                foreach (Book book in Helper.SearchBookByCondition(condition))
                {
                    Console.WriteLine("{0}-{1}", book.Title, book.Price);
                }
            }
        }
    }

      以上的实现方式采用委托delegate,在C#2.0中还提供了匿名方法,集合中过滤查询条件的代码可修改为:

    Helper.Condition condition = delegate(Book book) { return book.Title == "Book2"; };
    IList<Book> results = Helper.SearchBookByCondition(delegate(Book book) { return book.Title == "Book2"; });

       在C#3.0提供了Lambda表达式,则实现集合过滤方式为:

    IList<Book> results = Helper.SearchBookByCondition(book => book.Title == "Book2");

      但这样实现每次都要带类名Helper,我们希望IList自身就具有这个方法,C#3.0提供了扩展方法。

      3、C#3.0扩展方法实现方式

    public static class Helper
    {
        public delegate bool Condtion(Book book);
     
        public static IList<Book> Where(this IList<Book> books, Condtion condition)
        {
            IList < Book > results = new List<Book>();
            foreach (Book book in books)
            {
                if (condition(book))
                {
                    results.Add(book);
                }
            }
            return results;
        }
    }
    IList<Book> results = books.Where(book => book.Title == "Book2");

      5、IEnumberable实现方式

      由于IList都继承自IEnumberable,则可以通过扩展IEnumberable来实现。

    public static class Helper
    {
        public delegate bool Condtion<T>(T t);
        public static IEnumerable<T> Where<T>(this IEnumerable<T> items, Condtion<T> condition)
        {
            foreach (T t in items)
            {
                if (condition(t))
                {
                    yield return t;
                }
            }
        }
    }

       6、通用扩展类

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LINQTest
    {
        public class Extension
        {
            public delegate TResult Func<T, TResult>(T t);
    
            public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> filter)
            {
                foreach (T item in source)
                {
                    if (filter(item))
                    {
                        yield return item;
                    }
                }
            }
    
            public static IEnumerable<TResult> Select<T, TResult>(this IEnumerable<T> source, Func<T, TResult> selector)
            {
                foreach (T item in source)
                {
                    yield return selector(item);
                }
            }
        }
    }
    var result = books.Where(book => book.Title == "Book2").Select(book => new { 
                    Key = book.Title,Value=book.Price
                });
  • 相关阅读:
    这些年,产品经理们折腾过的原型工具
    这些年,产品经理们折腾过的原型工具
    这些年,产品经理们折腾过的原型工具
    区块链与微服务天生是一对
    区块链与微服务天生是一对
    区块链与微服务天生是一对
    区块链与微服务天生是一对
    OpenCV和Matlab
    OpenCV和Matlab
    现在最暴利的行业是什么?
  • 原文地址:https://www.cnblogs.com/libingql/p/3762532.html
Copyright © 2011-2022 走看看