c#中LINQ的基本用法(一)

 更新时间:2022年04月12日 16:01:53   作者:Ruby_Lu  
这篇文章介绍了c#中LINQ的基本用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

LINQ(Language Integrated Query,语言集成查询),在C#语言中集成了查询语法,可以用相同的语法访问不同的数据源。
LINQ提供了不同数据源的抽象层,所以可以使用相同的语法。
这里主要介绍LINQ的核心原理和C#中支持C# LINQ查询的语言扩展。

1.语法

使用LINQ查询出来自巴西的所以世界冠军。这里可以使用List<T>类的FindAll()方法,但使用LINQ查询语法更简单

    static void LINQQuery()
        {
          //
          var query = from r in Formula1.GetChampions()
                      where r.Country == "Brazil"
                      orderby r.Wins descending
                      select r;

          foreach (var r in query)
          {
            Console.WriteLine("{0:A}", r);
          }

        }

变量query只指定了LINQ查询。该查询不是通过这个赋值语句执行的,而是使用foreach循环访问查询时执行的。

2.扩展方法

编译器会转换LINQ查询,以调用方法而不是LINQ查询。LINQ为IEnumerable<T>接口提供了各种扩展方法(扩展方法在https://www.jb51.net/article/243984.htm介绍到),以便用户在实现了该接口的任意集合上使用LINQ查询。
定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable。只需要导入这个名称空间,就打开了这个类的扩展方法的作用域。下面是Where()扩展方法的实现代码:

    public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate)
        {
            foreach(TSource item in source)
            {
                if(predicate(item))
                {
                    yield return item;
                }
                
            }
        }

因为Where()作为一个泛型方法,所以它可以用于包含在集合中的任意类型。实现了IEnumerable<T>接口的任意集合都支持它。

3.推迟查询的执行

前面提到,在运行期间定义LINQ查询表达式时,查询不会运行。查询在迭代数据项时才会运行。
举个例子:

    static void DeferredQuery()
        {
          var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };

          var namesWithJ = from n in names
                           where n.StartsWith("J")
                           orderby n
                           select n;

          Console.WriteLine("First iteration");
          foreach (string name in namesWithJ)
          {
            Console.WriteLine(name);
          }
          Console.WriteLine();

          names.Add("John");
          names.Add("Jim");
          names.Add("Jack");
          names.Add("Denny");

          Console.WriteLine("Second iteration");
          foreach (string name in namesWithJ)
          {
            Console.WriteLine(name);
          }

        }

输出:

因为查询在迭代时才执行,所以在第一次输出后有添加项再输出,会显示又添加的项。
但在调用方法ToArray(),ToList等方法时,不会延迟执行:

    static void NotDeferredQuery()
        {
            var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };

            var namesWithJ = (from n in names
                             where n.StartsWith("J")
                             orderby n
                             select n).ToList();

            Console.WriteLine("First iteration");
            foreach (string name in namesWithJ)
            {
                Console.WriteLine(name);
            }
            Console.WriteLine();

            names.Add("John");
            names.Add("Jim");
            names.Add("Jack");
            names.Add("Denny");

            Console.WriteLine("Second iteration");
            foreach (string name in namesWithJ)
            {
                Console.WriteLine(name);
            }

        }

输出:

下面是用到的类,后续的也需要用到这些代码。

//这个类创建需要的列表
        public static class Formula1
          {
            private static List<Racer> racers;
            //返回一组赛车手
            public static IList<Racer> GetChampions()
            {
              if (racers == null)
              {
                racers = new List<Racer>(40);
                racers.Add(new Racer("Nino", "Farina", "Italy", 33, 5,           new int[] { 1950 }, new string[] { "Alfa Romeo" }));
                racers.Add(new Racer("Alberto", "Ascari", "Italy", 32, 10,           new int[] { 1952, 1953 }, new string[] { "Ferrari" }));
                racers.Add(new Racer("Juan Manuel", "Fangio", "Argentina", 51, 24,           new int[] { 1951, 1954, 1955, 1956, 1957 }, new string[] { "Alfa Romeo", "Maserati", "Mercedes", "Ferrari" }));
                racers.Add(new Racer("Mike", "Hawthorn", "UK", 45, 3,           new int[] { 1958 }, new string[] { "Ferrari" }));
                racers.Add(new Racer("Phil", "Hill", "USA", 48, 3,           new int[] { 1961 }, new string[] { "Ferrari" }));
                racers.Add(new Racer("John", "Surtees", "UK", 111, 6,           new int[] { 1964 }, new string[] { "Ferrari" }));
                racers.Add(new Racer("Jim", "Clark", "UK", 72, 25,           new int[] { 1963, 1965 }, new string[] { "Lotus" }));
                racers.Add(new Racer("Jack", "Brabham", "Australia", 125, 14,           new int[] { 1959, 1960, 1966 }, new string[] { "Cooper", "Brabham" }));
                racers.Add(new Racer("Denny", "Hulme", "New Zealand", 112, 8,           new int[] { 1967 }, new string[] { "Brabham" }));
              }

              return racers;
            }


            private static List<Team> teams;
            //返回一组冠军车队
            public static IList<Team> GetContructorChampions()
            {
              if (teams == null)
              {
                teams = new List<Team>()
                        {
                            new Team("Vanwall", 1958),
                            new Team("Cooper", 1959, 1960),
                            new Team("Ferrari", 1961, 1964, 1975, 1976, 1977, 1979, 1982, 1983, 1999,                     2000, 2001, 2002, 2003, 2004, 2007, 2008),
                            new Team("BRM", 1962),
                            new Team("Lotus", 1963, 1965, 1968, 1970, 1972, 1973, 1978),
                            new Team("Brabham", 1966, 1967),
                            new Team("Matra", 1969),
                            new Team("Tyrrell", 1971),
                            new Team("McLaren", 1974, 1984, 1985, 1988, 1989, 1990, 1991, 1998),
                            new Team("Williams", 1980, 1981, 1986, 1987, 1992, 1993, 1994, 1996, 1997),
                            new Team("Benetton", 1995),
                            new Team("Renault", 2005, 2006 ),
                            new Team("Brawn GP", 2009),
                            new Team("Red Bull Racing", 2010, 2011)
                        };
              }
              return teams;
            }

            private static List<Championship> championships;
            //返回GetChampionships类型的集合
            public static IEnumerable<Championship> GetChampionships()
            {
              if (championships == null)
              {
                championships = new List<Championship>();
                championships.Add(new Championship
                {
                  Year = 1950,
                  First = "Nino Farina",
                  Second = "Juan Manuel Fangio",
                  Third = "Luigi Fagioli"
                });
                championships.Add(new Championship
                {
                  Year = 1951,
                  First = "Juan Manuel Fangio",
                  Second = "Alberto Ascari",
                  Third = "Froilan Gonzalez"
                });
                championships.Add(new Championship
                {
                  Year = 1952,
                  First = "Alberto Ascari",
                  Second = "Nino Farina",
                  Third = "Piero Taruffi"
                });
                championships.Add(new Championship
                {
                  Year = 1953,
                  First = "Alberto Ascari",
                  Second = "Juan Manuel Fangio",
                  Third = "Nino Farina"
                });
                championships.Add(new Championship
                {
                  Year = 1954,
                  First = "Juan Manuel Fangio",
                  Second = "Froilan Gonzalez",
                  Third = "Mike Hawthorn"
                });
                championships.Add(new Championship
                {
                  Year = 1955,
                  First = "Juan Manuel Fangio",
                  Second = "Stirling Moss",
                  Third = "Eugenio Castellotti"
                });
                championships.Add(new Championship
                {
                  Year = 1956,
                  First = "Juan Manuel Fangio",
                  Second = "Stirling Moss",
                  Third = "Peter Collins"
                });
                
                
              }
              return championships;
            }
        }
//车手类
    
    [Serializable]
      public class Racer : IComparable<Racer>, IFormattable
      {
        public Racer(string firstName, string lastName, string country, int starts, int wins)
          : this(firstName, lastName, country, starts, wins, null, null)
        {
        }
        public Racer(string firstName, string lastName, string country, int starts,       int wins, IEnumerable<int> years, IEnumerable<string> cars)
        {
          this.FirstName = firstName;
          this.LastName = lastName;
          this.Country = country;
          this.Starts = starts;
          this.Wins = wins;
          this.Years = new List<int>(years);
          this.Cars = new List<string>(cars);
        }
        //单值属性
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Country { get; set; }
        public int Wins { get; set; }
        public int Starts { get; set; }
        //多值属性,车手可能多次获得冠军,所在的车队也可能不同
        public IEnumerable<string> Cars { get; private set; }
        public IEnumerable<int> Years { get; private set; }

        public override string ToString()
        {
          return String.Format("{0} {1}", FirstName, LastName);
        }

        public int CompareTo(Racer other)
        {
          if (other == null) return -1;
          return string.Compare(this.LastName, other.LastName);
        }

        public string ToString(string format)
        {
          return ToString(format, null);
        }

        public string ToString(string format,
              IFormatProvider formatProvider)
        {
          switch (format)
          {
            case null:
            case "N":
              return ToString();
            case "F":
              return FirstName;
            case "L":
              return LastName;
            case "C":
              return Country;
            case "S":
              return Starts.ToString();
            case "W":
              return Wins.ToString();
            case "A":
              return String.Format("{0} {1}, {2}; starts: {3}, wins: {4}",
                    FirstName, LastName, Country, Starts, Wins);
            default:
              throw new FormatException(String.Format("Format {0} not supported", format));
          }
        }
      }
//获得冠军的车队
        [Serializable]
        public class Team
        {
            public Team(string name, params int[] years)
            {
                this.Name = name;
                this.Years = new List<int>(years);
            }
            public string Name { get; private set; }
            public IEnumerable<int> Years { get; private set; }
        }
        
        
        //获奖选手和年份
          public class Championship
          {
            public int Year { get; set; }
            public string First { get; set; }
            public string Second { get; set; }
            public string Third { get; set; }
          }

到此这篇关于c#中LINQ的基本用法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#华氏温度和摄氏温度相互转换的方法

    C#华氏温度和摄氏温度相互转换的方法

    这篇文章主要介绍了C#华氏温度和摄氏温度相互转换的方法,涉及C#数学运算的相关技巧,非常简单实用,需要的朋友可以参考下
    2015-07-07
  • 浅谈C#指针问题

    浅谈C#指针问题

    在C#中,有时候希望通过指针来操作内存,这样可以提高效率。我们可以用unsafe关键字修饰含有指针操作的程序段
    2016-01-01
  • WPF仿三星手机充电界面实现代码

    WPF仿三星手机充电界面实现代码

    这篇文章主要为大家详细介绍了WPF仿三星手机充电界面实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • C#递归算法和排列算法

    C#递归算法和排列算法

    这篇文章介绍了C#的递归算法和排列算法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • 浅谈C#基础之类的访问修饰符

    浅谈C#基础之类的访问修饰符

    浅谈C#基础之类的访问修饰符,需要的朋友可以参考一下
    2013-03-03
  • C#基础语法:Base关键字学习笔记

    C#基础语法:Base关键字学习笔记

    这篇文章主要介绍了C#基础语法:Base关键字学习笔记,本文讲解了它的一些基础知识以及测试代码,需要的朋友可以参考下
    2015-06-06
  • C#操作INI文件的方法详解

    C#操作INI文件的方法详解

    INI文件全称是Initialization File的缩写,即初始化文件,是windows系统的系统配置文件所采用的存储格式,统管windows的各项配置。本文介绍了C#操作INI文件的方法,需要的可以参考一下
    2022-10-10
  • C#简单实现IOC容器的示例代码

    C#简单实现IOC容器的示例代码

    IoC 的原理是通过将对象的创建和依赖关系的管理交给外部容器来实现,从而降低了代码的耦合度,提高了代码的可维护性和可测试性,下面我们就来看看如何通过C#实现一个IOC容器吧
    2024-02-02
  • WinForm生成验证码图片的方法

    WinForm生成验证码图片的方法

    这篇文章主要介绍了WinForm生成验证码图片的方法,涉及WinForm字符串及图形操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • WPF如何自定义TabControl控件样式示例详解

    WPF如何自定义TabControl控件样式示例详解

    这篇文章主要给大家介绍了关于WPF如何自定义TabControl控件样式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-04-04

最新评论