C# Linq的实验代码

语言集成查询 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5 版中引入的功能,真正意义上的神来之笔。

在此之前,SQL 数据库、XML 文档、各种 Web 服务等等你需要分别学习它们各自的查询语言,有了LINQ,你可以使用语言关键字和熟悉的运算符(类似于SQL查询语言)统一处理,并且利用扩展方法可以无限扩展LINQ的功能。

LINQ之美让人惊叹,可以用点语法一路把指令串行写下去,让复杂的查询往往能用一句话搞定,勇哥当初着实为它痴迷了一把。

但是LINQ也有弱点,就是在出了问题调试时,不如一行行写下来的代码那么方便调试,另外我发现一段LINQ代码写下后,时间一长往往自己都不知道是干什么的,必须有详细的注释才可以。

这也是为什么在项目中,勇哥基本上不用LINQ的原因,另外这也跟勇哥从事的行业有关系,必竟机器设备用不到那么多的查询。

下面是勇哥当初学习LINQ时的测试代码,放上来算做个备份吧。


image.png

工程的结构如下:

image.png


Class1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqTest
{
    public static class StringExtern
    {
       
        public static string Foo(this string str)
        {
            return string.Format("这是string类的扩展方法Foo(),信息:{0}\n",str);
        }

        public static string ExtensionMethods()
        {
            var stus = new List<student>(StudentInfo.GetStudentList());
            IEnumerable<student> m1 = stus.Where(r => r.StuSex == student.Sex.男).
                OrderByDescending(r => r.StuAge).Select(r => r);
            StringBuilder sb1 = new StringBuilder();
            foreach (student m in m1)
            {
                sb1.Append(string.Format("{0:ALL}\n",m));
            }
            return sb1.ToString();
        }
    }
}

Class2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace LinqTest
{
    public delegate int TaskDelegate(); 
    class Class2
    {
        public UpdateUI onChage = null;
        public int MainFun()
        {
            var words = System.IO.File.ReadAllLines(Environment.CurrentDirectory + "\\英语四级单词txt完整版.txt",
                Encoding.UTF8);

            //查找文档中包含a的字符串
            Stopwatch sw1 = new Stopwatch();
            sw1.Restart();
            for (int i = 0; i < 10000; i++)
            {
                var query = from r in words
                            let keys = r.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
                            from key in keys
                            where key.Contains("a")
                            select key;
                var list = query.ToList();
                int nCount = list.Count;
            }

            onChage(string.Format("\n[非并行] 查找文档中包含a的字符串, 耗时: {0} 秒\n", sw1.ElapsedMilliseconds / 1000));

            sw1.Restart();
            for (int i = 0; i < 10000; i++)
            {
                var query = from r in words.AsParallel()
                            let keys = r.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
                            from key in keys
                            where key.Contains("a")
                            select key;
                var list = query.ToList();
                int nCount = list.Count;
            }
            onChage(string.Format("\n[并行] 查找文档中包含a的字符串, 耗时: {0} 秒\n", sw1.ElapsedMilliseconds / 1000));


            //计算short类型所有数字的和
            sw1.Restart();
            int[] ary1 = Enumerable.Range(0, short.MaxValue).ToArray();
            for (int i = 0; i < 100000; i++)
            {
                int sum1 = ary1.Sum();
            }
            onChage(string.Format("\n[非并行] 计算short类型所有数字的和, 耗时: {0} 秒\n", sw1.ElapsedMilliseconds / 1000));
            sw1.Restart();
            for (int i = 0; i < 100000; i++)
            {
                int sum1 = ary1.AsParallel().Sum();
            }
            onChage(string.Format("\n[并行] 计算short类型所有数字的和, 耗时: {0} 秒\n", sw1.ElapsedMilliseconds / 1000));


            //查找与排序
            // AsOrdered保持数据在数据源的顺序不变
            // orderby按用户指的升序或者降序排序
            sw1.Restart();
            for (int i = 0; i < 10000; i++)
            {
                var query1 = from r in words.AsParallel().AsOrdered()
                             where (r.Contains('a'))
                             select r;
                var list2 = query1.ToList();
            }
            onChage(string.Format("\n[并行] 查找与排序(AsOrdered), 耗时: {0} 秒\n", sw1.ElapsedMilliseconds / 1000));


            sw1.Restart();
            for (int i = 0; i < 10000; i++)
            {
                var query2 = from r in words.AsParallel()
                             where r.Contains('a')
                             orderby r ascending
                             select r;
                var list3 = query2.ToList();
            }
            onChage(string.Format("\n[并行] 查找与排序(orderby), 耗时: {0} 秒\n", sw1.ElapsedMilliseconds / 1000));

            Thread.Sleep(3000);

            return 1;
        }
    }
}

Class3.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Diagnostics;

namespace LinqClass3
{
    class Class3
    {
        public LinqTest.UpdateUI onChage = null;
        public int MainFun()
        {
            Stopwatch sw1 = new Stopwatch();
            sw1.Restart();
            onChage(string.Format("\n开始载入150万条记录.\n"));
            var dataAry = LoadData();
            onChage(string.Format("\n[并行] 载入150万条记录完毕, 耗时: {0} \n",
               sw1.ElapsedMilliseconds));
            
            sw1.Restart();
            var query1 = (from r in dataAry
                          where r.Value.Age >= 20 && r.Value.Age <= 25
                          select r).ToList();
            onChage(string.Format("\n[非并行] 查找记录中年龄在20到25的记录, 耗时: {0} \n",
                sw1.ElapsedMilliseconds));

            sw1.Restart();
            var query2 = (from r in dataAry.AsParallel()
                          where r.Value.Age >= 20 && r.Value.Age <= 25
                          select r).ToList();
            onChage(string.Format("\n[并行] 查找记录中年龄在20到25的记录, 耗时: {0} \n",
                sw1.ElapsedMilliseconds ));
            return 1;
        }

        public static ConcurrentDictionary<int, student> LoadData()
        {
            var m1=new ConcurrentDictionary<int,student>();
            Parallel.For(0, 1500000,(i)=>
            {
                var d1 = new student()
                {
                    Name="lxy"+i,
                    Id=i,
                    Age=i%151,
                    CreateTime=DateTime.Now.AddSeconds(i)
                };
                m1.TryAdd(i, d1);
            });
            return m1;
        }

        public void TaskCompleted(IAsyncResult ir)
        {
            var d1 = ir.AsyncState as LinqTest.TaskDelegate;
            d1.EndInvoke(ir);
            onChage(string.Format("\n计算完成.\n"));
        }
    }

    public class student
    {
        public string Name { get; set; }
        public int Id { get; set; }
        public int Age { get; set; }
        public DateTime CreateTime { get; set; }
    }

}

Formula1.cs

using System.Collections.Generic;

namespace LinqTest
{
    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" }));
                racers.Add(new Racer("Graham", "Hill", "UK", 176, 14, new int[] { 1962, 1968 }, new string[] { "BRM", "Lotus" }));
                racers.Add(new Racer("Jochen", "Rindt", "Austria", 60, 6, new int[] { 1970 }, new string[] { "Lotus" }));
                racers.Add(new Racer("Jackie", "Stewart", "UK", 99, 27, new int[] { 1969, 1971, 1973 }, new string[] { "Matra", "Tyrrell" }));
                racers.Add(new Racer("Emerson", "Fittipaldi", "Brazil", 143, 14, new int[] { 1972, 1974 }, new string[] { "Lotus", "McLaren" }));
                racers.Add(new Racer("James", "Hunt", "UK", 91, 10, new int[] { 1976 }, new string[] { "McLaren" }));
                racers.Add(new Racer("Mario", "Andretti", "USA", 128, 12, new int[] { 1978 }, new string[] { "Lotus" }));
                racers.Add(new Racer("Jody", "Scheckter", "South Africa", 112, 10, new int[] { 1979 }, new string[] { "Ferrari" }));
                racers.Add(new Racer("Alan", "Jones", "Australia", 115, 12, new int[] { 1980 }, new string[] { "Williams" }));
                racers.Add(new Racer("Keke", "Rosberg", "Finland", 114, 5, new int[] { 1982 }, new string[] { "Williams" }));
                racers.Add(new Racer("Niki", "Lauda", "Austria", 173, 25, new int[] { 1975, 1977, 1984 }, new string[] { "Ferrari", "McLaren" }));
                racers.Add(new Racer("Nelson", "Piquet", "Brazil", 204, 23, new int[] { 1981, 1983, 1987 }, new string[] { "Brabham", "Williams" }));
                racers.Add(new Racer("Ayrton", "Senna", "Brazil", 161, 41, new int[] { 1988, 1990, 1991 }, new string[] { "McLaren" }));
                racers.Add(new Racer("Nigel", "Mansell", "UK", 187, 31, new int[] { 1992 }, new string[] { "Williams" }));
                racers.Add(new Racer("Alain", "Prost", "France", 197, 51, new int[] { 1985, 1986, 1989, 1993 }, new string[] { "McLaren", "Williams" }));
                racers.Add(new Racer("Damon", "Hill", "UK", 114, 22, new int[] { 1996 }, new string[] { "Williams" }));
                racers.Add(new Racer("Jacques", "Villeneuve", "Canada", 165, 11, new int[] { 1997 }, new string[] { "Williams" }));
                racers.Add(new Racer("Mika", "Hakkinen", "Finland", 160, 20, new int[] { 1998, 1999 }, new string[] { "McLaren" }));
                racers.Add(new Racer("Michael", "Schumacher", "Germany", 250, 91, new int[] { 1994, 1995, 2000, 2001, 2002, 2003, 2004 }, new string[] { "Benetton", "Ferrari" }));
                racers.Add(new Racer("Fernando", "Alonso", "Spain", 132, 21, new int[] { 2005, 2006 }, new string[] { "Renault" }));
                racers.Add(new Racer("Kimi", "Räikkönen", "Finland", 148, 17, new int[] { 2007 }, new string[] { "Ferrari" }));
                racers.Add(new Racer("Lewis", "Hamilton", "UK", 44, 9, new int[] { 2008 }, new string[] { "McLaren" }));
            }

            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 )
                };
            }
            return teams;
        }


    }

}

Racer.cs

using System;
using System.Collections.Generic;

namespace LinqTest
{
    [Serializable]
    public class Racer : IComparable<Racer>, IFormattable 
    {
        public Racer(string firstName = null, string lastName = null, string country = null, int starts = 0, int wins = 0, IEnumerable<int> years = null, IEnumerable<string> cars = null)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Country = country;
                        this.Starts = starts;
            this.Wins = wins;

  
            var yearsList = new List<int>();
            foreach (var year in years)
            {
                yearsList.Add(year);
            }
            this.Years = yearsList.ToArray();
            var carList = new List<string>();
            foreach (var car in cars)
            {
                carList.Add(car);
            }
            this.Cars = carList.ToArray();


        }
        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 string[] Cars { get; private set; } //获得冠军所用的车
        public int[] Years { get; private set; }    //一个赛手可能多个年份获得冠军

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

        public int CompareTo(Racer other)
        {
            if (other == null) throw new ArgumentNullException("other");

            return this.LastName.CompareTo(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));
            }  
        }


    }
}


student.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqTest
{

    public class StuClass
    {
        public enum ClassTeam
        {
            初一一班,
            初一二班,
            初二一班,
            初二二班,
            初三一班,
            初三二班
        }

        public StuClass(ClassTeam classname,params int[] year)
        {
            this.StuClassName = classname;
            this.years = year;
        }
        public ClassTeam StuClassName { get; set; }
        public int[] years { get; set; }
    }

    public class StuClassInfo
    {
        private static IList<StuClass> stuClassList;
        public static IList<StuClass> LoadStuClassInfo()
        {
            if (stuClassList == null)
            {
                stuClassList = new List<StuClass>()
                {
                new StuClass(StuClass.ClassTeam.初二二班,2011,2013,2014,2015),
                new StuClass(StuClass.ClassTeam.初三二班,2012,2015,2018),
                new StuClass(StuClass.ClassTeam.初一二班,2012,2013,2018),
                new StuClass(StuClass.ClassTeam.初一一班,2013,2018),
                new StuClass(StuClass.ClassTeam.初三一班,2012,2013,2014,2018)
                };
            }
            return stuClassList;

        }
    }

    public class StudentInfo
    {
        private static IList<student> StudentList;

        public static IList<student> GetStudentList()
        {
            if (StudentList == null)
            {
                StudentList = new List<student>();
                StudentList.Add(new student("刘备",
                    student.Sex.男,
                    18, 
                    new int[] { 2010, 2014,2015},
                    new string[] { student.winType.百米跑.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.跳远.ToString()
                    }));
                StudentList.Add(new student("张飞",
                    student.Sex.男,
                    13,
                    new int[] { 2009, 2010, 2015 },
                    new string[] { student.winType.数字竞赛.ToString(),
                    student.winType.作文竞赛.ToString(),
                    student.winType.唱歌.ToString()
                    }));
                StudentList.Add(new student("符大乔",
                    student.Sex.女,
                    12,
                    new int[] { 2010, 2014 },
                    new string[] { student.winType.作文竞赛.ToString(),
                    student.winType.唱歌.ToString(),
                    }));
                StudentList.Add(new student("李香兰",
                    student.Sex.女,
                    13,
                    new int[] { 2012, 2012 },
                    new string[] { student.winType.跳绳.ToString(),
                    student.winType.唱歌.ToString(),
                    }));
                StudentList.Add(new student("曹操",
                    student.Sex.男,
                    15,
                    new int[] { 2014, 2015 },
                    new string[] { student.winType.作文竞赛.ToString(),
                    student.winType.唱歌.ToString(),
                    }));
                StudentList.Add(new student("诸葛亮",
                    student.Sex.男,
                    16,
                    new int[] { 2008, 2009, 2010,2011,2012 },
                    new string[] { student.winType.数字竞赛.ToString(),
                    student.winType.作文竞赛.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.百米跑.ToString()
                    }));
                StudentList.Add(new student("赵云",
                   student.Sex.男,
                   17,
                   new int[] { 2009, 2012, 2015 },
                   new string[] { student.winType.跳绳.ToString(),
                    student.winType.跳远.ToString(),
                    student.winType.百米跑.ToString()
                    }));
                StudentList.Add(new student("许诸",
                    student.Sex.男,
                    18,
                    new int[] { 2008, 2009, 2010, 2011, 2012 },
                    new string[] { student.winType.百米跑.ToString(),
                    student.winType.跳远.ToString(),
                    student.winType.百米跑.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.百米跑.ToString()
                    }));
               StudentList.Add(new student("周瑜",
                   student.Sex.男,
                   17,
                   new int[] { 2011, 2014 },
                   new string[] { student.winType.作文竞赛.ToString(),
                        student.winType.数字竞赛.ToString(),
                        }));
               StudentList.Add(new student("黄盖",
                    student.Sex.男,
                    22,
                    new int[] { 2014, 2015 },
                    new string[] { student.winType.跳远.ToString(),
                    student.winType.跳绳.ToString(),
                    }));
               StudentList.Add(new student("貂婵",
                 student.Sex.女,
                 18,
                 new int[] { 2018,2019,2010, 2014 },
                 new string[] { student.winType.作文竞赛.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.唱歌.ToString()
                    }));
               StudentList.Add(new student("刘小勇",
                     student.Sex.男,
                     28,
                     new int[] { 2018, 2019, 2010, 2014 },
                     new string[] { student.winType.作文竞赛.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.唱歌.ToString()
                    }));
               StudentList.Add(new student("李宇春",
                     student.Sex.人妖,
                     21,
                     new int[] { 2018, 2019, 2010, 2014 },
                     new string[] { student.winType.唱歌.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.唱歌.ToString(),
                    student.winType.唱歌.ToString()
                    }));
            }
            return StudentList;
        }
    }

    public class student:IComparable<student>,IFormattable
    {
        public enum winType
        {
            跳绳, 百米跑, 跳远, 数字竞赛, 作文竞赛, 唱歌
        }

        public enum Sex
        {
            男 = 0,
            女,
            人妖
        }

        public student(string name = "", Sex sex = Sex.人妖, int age = 2, IEnumerable<int> years = null,
            IEnumerable<string> wintype=null)
        {
            this.StuName = name;
            this.StuSex = sex;
            this.StuAge = age;

            var list1=new List<int>();
            foreach (int m in years)
            {
                list1.Add(m);
            }
            StuYears = list1.ToArray();

            var list2 = new List<string>();
            foreach (string m in wintype)
            {
                list2.Add(m);
            }
            StuWinType = list2.ToArray();
        }

        public string StuName { get; set; }
        public Sex StuSex { get; set; }
        public int StuAge { get; set; }
        public int[] StuYears { get; private set; }       //哪一年获奖
        public string[] StuWinType { get; private set; }  //获奖时的获奖类型

        public int CompareTo(student other)
        {
            if (other == null)
                throw new ArgumentNullException("other");
            return this.StuAge.CompareTo(other.StuAge);
        }

        private string getStr<T>(IEnumerable<T> param)
        {
            StringBuilder sb1 = new StringBuilder();
            sb1.Append("[");
            foreach (T m in param)
            {
                sb1.Append(m.ToString());
                sb1.Append(",");
            }
            sb1.Remove(sb1.Length - 1, 1);
            sb1.Append("]");
            return sb1.ToString();
        }


        public string ToString(string format,IFormatProvider formatProvider)
        {
            StringBuilder sb1 = null;
            switch (format)
            {
                case "N":
                    return StuName;
                case "S":
                    return StuSex.ToString();
                case "A":
                    return StuAge.ToString();
                case "Y":
                    return getStr<int>(StuYears);
                case "T":
                    return getStr<string>(StuWinType);
                case "ALL":
                    return string.Format("{0},{1},{2},{3},{4}",
                        StuName,
                        StuSex.ToString(),
                        StuAge.ToString(),
                        getStr<int>(StuYears),
                        getStr<string>(StuWinType)
                        );
                default:
                    throw new FormatException(String.Format("Format {0} not supported", format));
            }
        }



    }
}


Team.cs

using System;

namespace LinqTest
{
    [Serializable]
    public class Team
    {
        public Team(string name, params int[] years)
        {
            this.Name = name;
            this.Years = years;
        }
        public string Name { get; private set; }
        public int[] Years { get; private set; }
    }
}


MainForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Reflection;

namespace LinqTest
{
    public delegate void UpdateUI(string msg);
    public partial class MainForm : Form
    {
        Class2 c2 = null;
        LinqClass3.Class3 c3 = null;
        public MainForm()
        {
            InitializeComponent();
        }

        private void btnTest1_Click(object sender, EventArgs e)
        {
            //button1
            var query = from r in Formula1.GetChampions()
                        where r.Country == "Brazil"
                        orderby r.Wins descending
                        select r;
            foreach (Racer r in query)
            {
                rtbMsg.AppendText(string.Format("{0},{1},Starts:{2},Wins:{3}\n", 
                    r.FirstName,r.LastName,r.Starts,r.Wins));
            }
        }

        private void btnTest2_Click(object sender, EventArgs e)
        {
            //基本查询
            var query = from r in StudentInfo.GetStudentList()
                        where r.StuSex == student.Sex.女
                        orderby r.StuAge descending
                        select r;

            foreach (student m in query)
            {
                rtbMsg.AppendText(string.Format("{0:ALL}\n",m));
            }
        }

        private void btnTest3_Click(object sender, EventArgs e)
        {
            //扩展方法
            string str1 = "刘小勇";
            this.rtbMsg.AppendText(str1.Foo());

            this.rtbMsg.AppendText(StringExtern.ExtensionMethods());
        }

        private void btnTest4_Click(object sender, EventArgs e)
        {
            //一些筛选的例子
            var query = from r in StudentInfo.GetStudentList()
                        where r.StuYears.Length > 3 && r.StuAge > 14
                        select r;

            this.rtbMsg.AppendText("\n\n筛选获奖年数大于3,并且年龄大于14岁的人\n");
            foreach (student m in query)
            {
                this.rtbMsg.AppendText(string.Format("{0:ALL}\n",m));
            }


            var query1 = from r in StudentInfo.GetStudentList()
                         where r.StuName.StartsWith("刘")
                         select r;
            this.rtbMsg.AppendText("\n\n筛选姓刘的人\n");
            foreach (student m in query1)
            {
                this.rtbMsg.AppendText(string.Format("{0:ALL}\n", m));
            }


            var query2 = StudentInfo.GetStudentList().Where(r => r.StuName.StartsWith("刘")).Select(r => r);
            this.rtbMsg.AppendText("\n\n扩展方法筛选姓刘的人\n");
            foreach (student m in query2)
            {
                this.rtbMsg.AppendText(string.Format("{0:ALL}\n", m));
            }


            this.rtbMsg.AppendText("\n\n扩展方法按类型筛选\n");
            object[] obj ={ 1, 2, 3, "刘小勇", "张辽", 55, 22, 18 };
            var query5 = obj.OfType<string>();
            foreach (string m in query5)
            {
                this.rtbMsg.AppendText(string.Format("{0}\n",m));
            }


            this.rtbMsg.AppendText("\n\n[复合from子句] \n");
            var query6 = from r in StudentInfo.GetStudentList()
                         from c in r.StuWinType
                         where c == student.winType.唱歌.ToString()
                         select r.StuName + "," + r.StuAge;
            foreach (string m in query6)
            {
                this.rtbMsg.AppendText(string.Format("{0}\n", m));
            }


            this.rtbMsg.AppendText("\n\n[排序的例子] 按姓名,年龄,性别,降序排序\n");
            var query7 = from r in StudentInfo.GetStudentList()
                         where r.StuAge > 5
                         orderby r.StuName,r.StuAge,r.StuSex descending
                         select r;
            foreach (student m in query7)
            {
                this.rtbMsg.AppendText(string.Format("{0:ALL}\n", m));
            }

            this.rtbMsg.AppendText("\n\n查找性别为男的记录\n");
            var query8 = (from r in StudentInfo.GetStudentList()
                          where r.StuSex == student.Sex.男
                          select r).ToList();
            foreach (student m in query8)
            {
                this.rtbMsg.AppendText(string.Format("{0:ALL}\n",m));
            }
            this.rtbMsg.AppendText("\n[取前几条记录] 查找性别为男的前5条记录\n");
            var query9 = (from r in StudentInfo.GetStudentList()
                          where r.StuSex == student.Sex.男
                          select r).Take(5);
            foreach (student m in query9)
            {
                this.rtbMsg.AppendText(string.Format("{0:ALL}\n", m));
            }


            this.rtbMsg.AppendText("\n[分组] 查找不同年龄段的人有多少获奖\n");
            var query10 = from r in StudentInfo.GetStudentList()
                          group r by r.StuAge into g
                          orderby g.Count() descending, g.Key
                          where g.Count() > 0
                          select new
                          {
                              stuyears = g.Key,
                              sums = g.Count()
                          };
            foreach (var m in query10)
            {
                this.rtbMsg.AppendText(string.Format("{0}岁的人获奖次数:{1}\n",m.stuyears, m.sums));
            }

            this.rtbMsg.AppendText("\n[分组] 对嵌套的对象分组\n");
            var query11 = from r in StudentInfo.GetStudentList()
                          group r by r.StuAge into g
                          orderby g.Count() descending, g.Key
                          where g.Count() > 0
                          select new
                          {
                              stuyears = g.Key,
                              sums = g.Count(),
                              stuname1 = from r1 in g
                                         orderby r1.StuName
                                         select r1.StuName
                          };
            foreach (var m in query11)
            {
                this.rtbMsg.AppendText(string.Format("{0}岁的人获奖次数:{1},人员名称:",
                    m.stuyears, m.sums));
                foreach(var k in m.stuname1)
                {
                    this.rtbMsg.AppendText(string.Format("{0},", k.ToString()));
                }
                this.rtbMsg.AppendText("\n");
            }

            this.rtbMsg.AppendText("\n[连接] 学生获奖年份,班级获奖年份连接起来\n");
            var students = from r in StudentInfo.GetStudentList()
                          from y in r.StuYears
                          where y > 2009
                          select new
                          {
                             name=r.StuName,
                             year=y,
                             sex=r.StuSex
                          };
            var teams = from r in StuClassInfo.LoadStuClassInfo()
                          from y in r.years
                          where y > 2009
                          select new
                          {
                              teamYear=y,
                              teamName=r.StuClassName
                          };
            var StudentAndTeam = from r in students
                                 join t in teams on r.year equals t.teamYear
                                 orderby t.teamName
                                 select new
                                 {
                                     stuName=r.name,
                                     stuSex=r.sex,
                                     teamsName=t.teamName,
                                     teamsYear=t.teamYear
                                 };
            foreach (var item in StudentAndTeam)
            {
                this.rtbMsg.AppendText(string.Format("班级名称:{0},学生名称:{1}, 性别:{2}, 获奖年份: {3}\n",
                  item.teamsName,item.stuName,item.stuSex,item.teamsYear));
            }


            this.rtbMsg.AppendText("\n[集合操作] 取百米跑的记录\n");
            Func<string, IEnumerable<student>> GetWintype =
                (wintype) => from r in StudentInfo.GetStudentList()
                             from y in r.StuWinType
                             where y == wintype
                             orderby r.StuName
                             select r;
            foreach (student m in GetWintype(student.winType.百米跑.ToString()))
            {
                this.rtbMsg.AppendText(string.Format("{0:ALL}\n", m));
            }

            this.rtbMsg.AppendText("\n[集合操作] 取百米跑,唱歌的交集记录\n");
            foreach (student m in GetWintype(student.winType.百米跑.ToString()).Intersect(GetWintype(
                student.winType.唱歌.ToString())))
            {
                this.rtbMsg.AppendText(string.Format("{0:ALL}\n", m));
            }

            this.rtbMsg.AppendText("\n[ZIP操作] 把两个相关的序列合并成一个\n");
            var queryName = from r in StudentInfo.GetStudentList()
                            where r.StuAge > 20
                            orderby r.StuAge
                            select new
                            {
                                name=r.StuName
                            };
            var querySex = from r in StudentInfo.GetStudentList()
                           where r.StuAge > 20
                           orderby r.StuAge
                           select new
                           {
                               sex=r.StuSex
                           };
            var queryZip = queryName.Zip(querySex, (first, second) =>
            {
                return first.name + "," + second.sex;
            });

            foreach (var m in queryZip)
            {
                this.rtbMsg.AppendText(string.Format("{0}\n",m.ToString()));
            }


            this.rtbMsg.AppendText("\n[分区操作] 用于数据分页\n");
            int pagesize = (int)Math.Ceiling((double)StudentInfo.GetStudentList().Count /5);
            for (int page = 0; page < pagesize; page++)
            {
                this.rtbMsg.AppendText(string.Format("page={0}\n", page + 1));
                var queryPage = (from r in StudentInfo.GetStudentList()
                                 orderby r.StuAge
                                 select r.StuName + "," + r.StuAge + "," + r.StuSex
                                ).Skip(page * 5).Take(5);
                foreach (string m in queryPage)
                {
                    this.rtbMsg.AppendText(string.Format("{0}\n",m));
                }
                this.rtbMsg.AppendText(string.Format("\n"));
            }

            this.rtbMsg.AppendText("\n[转换] ToList()会立即执行查询,ToLookUp()用于创建一对多的键值对\n");
            var queryLookUp = (from r in StudentInfo.GetStudentList()
                               from y in r.StuWinType
                               where y == student.winType.唱歌.ToString()
                               select new
                               {
                                   name=r.StuName,
                                   wintype=y
                               }
                               ).ToLookup(r1 => r1.wintype, r2 =>r2.name);
            foreach (var m in queryLookUp[student.winType.唱歌.ToString()])
            {
                this.rtbMsg.AppendText(string.Format("{0}\n", m.ToString()));
            }


        }

        private void btnTest5_Click(object sender, EventArgs e)
        {
            //并行LINQ
            const long s1 = 100000000;
            int[] data = new int[s1];
            var r1 = new Random();
            for (int i = 0; i < s1; i++)
            {
                data[i] = r1.Next(40);
            }

            Stopwatch sw1 = new Stopwatch();
            sw1.Restart();
            var sum = (from r in data.AsParallel()
                       where r < 30
                       select r).Sum();
            rtbMsg.AppendText(string.Format("\n并行LINQ结束,耗时:{0}\n",sw1.ElapsedMilliseconds));
            //运行前观察任务管理器,会看到多核CPU全部开始工作
        }

        private void btnTest7_Click(object sender, EventArgs e)
        {
            //并行LINQ2
            c2 = new Class2();
            c2.onChage = this.onChage;

            TaskDelegate tg = new TaskDelegate(c2.MainFun);
            IAsyncResult ir = tg.BeginInvoke(null,null);
            while(!ir.IsCompleted)
            {
                this.rtbMsg.AppendText(".");
                Thread.Sleep(100);
                Application.DoEvents();
            }
            this.rtbMsg.AppendText("\n 测试完成.\n");

        }

        private void onChage(string msg)
        {
            StackTrace trace = new StackTrace();
            //获取调用此方法的方法类名
            string name= trace.GetFrame(1).GetMethod().DeclaringType.ToString();
            //获取调用此方法的方法名
            string funname=trace.GetFrame(1).GetMethod().ToString();

         
            if (this.rtbMsg.InvokeRequired)
            {
                switch (name)
                {
                    case "LinqClass3.Class3":
                        rtbMsg.Invoke(c3.onChage, new object[] { msg });
                        break;
                    case "LinqTest.Class2":
                        rtbMsg.Invoke(c2.onChage, new object[] { msg });
                        break;
                }
                
            }
            else
                this.rtbMsg.AppendText(msg);
        }

        private void btnTest8_Click(object sender, EventArgs e)
        {
            //并行LINQ3
            c3 = new LinqClass3.Class3();
            c3.onChage=this.onChage;
            TaskDelegate dg1 = c3.MainFun;
            dg1.BeginInvoke(c3.TaskCompleted, dg1);
        }

        private void button1_Click(object sender, EventArgs e)
        {

        }
    }
}

下面是程序在勇哥的电脑的输出结果(并行与电脑CPU的核心有关系),请参考:

Ayrton,Senna,Starts:161,Wins:41
Nelson,Piquet,Starts:204,Wins:23
Emerson,Fittipaldi,Starts:143,Wins:14

===========================================

貂婵,女,18,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]
李香兰,女,13,[2012,2012],[跳绳,唱歌]
符大乔,女,12,[2010,2014],[作文竞赛,唱歌]

===========================================

这是string类的扩展方法Foo(),信息:刘小勇
刘小勇,男,28,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]
黄盖,男,22,[2014,2015],[跳远,跳绳]
刘备,男,18,[2010,2014,2015],[百米跑,唱歌,跳远]
许诸,男,18,[2008,2009,2010,2011,2012],[百米跑,跳远,百米跑,唱歌,百米跑]
赵云,男,17,[2009,2012,2015],[跳绳,跳远,百米跑]
周瑜,男,17,[2011,2014],[作文竞赛,数字竞赛]
诸葛亮,男,16,[2008,2009,2010,2011,2012],[数字竞赛,作文竞赛,唱歌,唱歌,百米跑]
曹操,男,15,[2014,2015],[作文竞赛,唱歌]
张飞,男,13,[2009,2010,2015],[数字竞赛,作文竞赛,唱歌]

===========================================

筛选获奖年数大于3,并且年龄大于14岁的人
诸葛亮,男,16,[2008,2009,2010,2011,2012],[数字竞赛,作文竞赛,唱歌,唱歌,百米跑]
许诸,男,18,[2008,2009,2010,2011,2012],[百米跑,跳远,百米跑,唱歌,百米跑]
貂婵,女,18,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]
刘小勇,男,28,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]
李宇春,人妖,21,[2018,2019,2010,2014],[唱歌,唱歌,唱歌,唱歌]


筛选姓刘的人
刘备,男,18,[2010,2014,2015],[百米跑,唱歌,跳远]
刘小勇,男,28,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]


扩展方法筛选姓刘的人
刘备,男,18,[2010,2014,2015],[百米跑,唱歌,跳远]
刘小勇,男,28,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]


扩展方法按类型筛选
刘小勇
张辽


[复合from子句] 
刘备,18
张飞,13
符大乔,12
李香兰,13
曹操,15
诸葛亮,16
诸葛亮,16
许诸,18
貂婵,18
貂婵,18
貂婵,18
刘小勇,28
刘小勇,28
刘小勇,28
李宇春,21
李宇春,21
李宇春,21
李宇春,21


[排序的例子] 按姓名,年龄,性别,降序排序
曹操,男,15,[2014,2015],[作文竞赛,唱歌]
貂婵,女,18,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]
符大乔,女,12,[2010,2014],[作文竞赛,唱歌]
黄盖,男,22,[2014,2015],[跳远,跳绳]
李香兰,女,13,[2012,2012],[跳绳,唱歌]
李宇春,人妖,21,[2018,2019,2010,2014],[唱歌,唱歌,唱歌,唱歌]
刘备,男,18,[2010,2014,2015],[百米跑,唱歌,跳远]
刘小勇,男,28,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]
许诸,男,18,[2008,2009,2010,2011,2012],[百米跑,跳远,百米跑,唱歌,百米跑]
张飞,男,13,[2009,2010,2015],[数字竞赛,作文竞赛,唱歌]
赵云,男,17,[2009,2012,2015],[跳绳,跳远,百米跑]
周瑜,男,17,[2011,2014],[作文竞赛,数字竞赛]
诸葛亮,男,16,[2008,2009,2010,2011,2012],[数字竞赛,作文竞赛,唱歌,唱歌,百米跑]


查找性别为男的记录
刘备,男,18,[2010,2014,2015],[百米跑,唱歌,跳远]
张飞,男,13,[2009,2010,2015],[数字竞赛,作文竞赛,唱歌]
曹操,男,15,[2014,2015],[作文竞赛,唱歌]
诸葛亮,男,16,[2008,2009,2010,2011,2012],[数字竞赛,作文竞赛,唱歌,唱歌,百米跑]
赵云,男,17,[2009,2012,2015],[跳绳,跳远,百米跑]
许诸,男,18,[2008,2009,2010,2011,2012],[百米跑,跳远,百米跑,唱歌,百米跑]
周瑜,男,17,[2011,2014],[作文竞赛,数字竞赛]
黄盖,男,22,[2014,2015],[跳远,跳绳]
刘小勇,男,28,[2018,2019,2010,2014],[作文竞赛,唱歌,唱歌,唱歌]

[取前几条记录] 查找性别为男的前5条记录
刘备,男,18,[2010,2014,2015],[百米跑,唱歌,跳远]
张飞,男,13,[2009,2010,2015],[数字竞赛,作文竞赛,唱歌]
曹操,男,15,[2014,2015],[作文竞赛,唱歌]
诸葛亮,男,16,[2008,2009,2010,2011,2012],[数字竞赛,作文竞赛,唱歌,唱歌,百米跑]
赵云,男,17,[2009,2012,2015],[跳绳,跳远,百米跑]

[分组] 查找不同年龄段的人有多少获奖
18岁的人获奖次数:3
13岁的人获奖次数:2
17岁的人获奖次数:2
12岁的人获奖次数:1
15岁的人获奖次数:1
16岁的人获奖次数:1
21岁的人获奖次数:1
22岁的人获奖次数:1
28岁的人获奖次数:1

[分组] 对嵌套的对象分组
18岁的人获奖次数:3,人员名称:貂婵,刘备,许诸,
13岁的人获奖次数:2,人员名称:李香兰,张飞,
17岁的人获奖次数:2,人员名称:赵云,周瑜,
12岁的人获奖次数:1,人员名称:符大乔,
15岁的人获奖次数:1,人员名称:曹操,
16岁的人获奖次数:1,人员名称:诸葛亮,
21岁的人获奖次数:1,人员名称:李宇春,
22岁的人获奖次数:1,人员名称:黄盖,
28岁的人获奖次数:1,人员名称:刘小勇,

[连接] 学生获奖年份,班级获奖年份连接起来
班级名称:初一一班,学生名称:貂婵, 性别:女, 获奖年份: 2018
班级名称:初一一班,学生名称:刘小勇, 性别:男, 获奖年份: 2018
班级名称:初一一班,学生名称:李宇春, 性别:人妖, 获奖年份: 2018
班级名称:初一二班,学生名称:李香兰, 性别:女, 获奖年份: 2012
班级名称:初一二班,学生名称:李香兰, 性别:女, 获奖年份: 2012
班级名称:初一二班,学生名称:诸葛亮, 性别:男, 获奖年份: 2012
班级名称:初一二班,学生名称:赵云, 性别:男, 获奖年份: 2012
班级名称:初一二班,学生名称:许诸, 性别:男, 获奖年份: 2012
班级名称:初一二班,学生名称:貂婵, 性别:女, 获奖年份: 2018
班级名称:初一二班,学生名称:刘小勇, 性别:男, 获奖年份: 2018
班级名称:初一二班,学生名称:李宇春, 性别:人妖, 获奖年份: 2018
班级名称:初二二班,学生名称:刘备, 性别:男, 获奖年份: 2014
班级名称:初二二班,学生名称:刘备, 性别:男, 获奖年份: 2015
班级名称:初二二班,学生名称:张飞, 性别:男, 获奖年份: 2015
班级名称:初二二班,学生名称:符大乔, 性别:女, 获奖年份: 2014
班级名称:初二二班,学生名称:曹操, 性别:男, 获奖年份: 2014
班级名称:初二二班,学生名称:曹操, 性别:男, 获奖年份: 2015
班级名称:初二二班,学生名称:诸葛亮, 性别:男, 获奖年份: 2011
班级名称:初二二班,学生名称:赵云, 性别:男, 获奖年份: 2015
班级名称:初二二班,学生名称:许诸, 性别:男, 获奖年份: 2011
班级名称:初二二班,学生名称:周瑜, 性别:男, 获奖年份: 2011
班级名称:初二二班,学生名称:周瑜, 性别:男, 获奖年份: 2014
班级名称:初二二班,学生名称:黄盖, 性别:男, 获奖年份: 2014
班级名称:初二二班,学生名称:黄盖, 性别:男, 获奖年份: 2015
班级名称:初二二班,学生名称:貂婵, 性别:女, 获奖年份: 2014
班级名称:初二二班,学生名称:刘小勇, 性别:男, 获奖年份: 2014
班级名称:初二二班,学生名称:李宇春, 性别:人妖, 获奖年份: 2014
班级名称:初三一班,学生名称:刘备, 性别:男, 获奖年份: 2014
班级名称:初三一班,学生名称:符大乔, 性别:女, 获奖年份: 2014
班级名称:初三一班,学生名称:李香兰, 性别:女, 获奖年份: 2012
班级名称:初三一班,学生名称:李香兰, 性别:女, 获奖年份: 2012
班级名称:初三一班,学生名称:曹操, 性别:男, 获奖年份: 2014
班级名称:初三一班,学生名称:诸葛亮, 性别:男, 获奖年份: 2012
班级名称:初三一班,学生名称:赵云, 性别:男, 获奖年份: 2012
班级名称:初三一班,学生名称:许诸, 性别:男, 获奖年份: 2012
班级名称:初三一班,学生名称:周瑜, 性别:男, 获奖年份: 2014
班级名称:初三一班,学生名称:黄盖, 性别:男, 获奖年份: 2014
班级名称:初三一班,学生名称:貂婵, 性别:女, 获奖年份: 2018
班级名称:初三一班,学生名称:貂婵, 性别:女, 获奖年份: 2014
班级名称:初三一班,学生名称:刘小勇, 性别:男, 获奖年份: 2018
班级名称:初三一班,学生名称:刘小勇, 性别:男, 获奖年份: 2014
班级名称:初三一班,学生名称:李宇春, 性别:人妖, 获奖年份: 2018
班级名称:初三一班,学生名称:李宇春, 性别:人妖, 获奖年份: 2014
班级名称:初三二班,学生名称:刘备, 性别:男, 获奖年份: 2015
班级名称:初三二班,学生名称:张飞, 性别:男, 获奖年份: 2015
班级名称:初三二班,学生名称:李香兰, 性别:女, 获奖年份: 2012
班级名称:初三二班,学生名称:李香兰, 性别:女, 获奖年份: 2012
班级名称:初三二班,学生名称:曹操, 性别:男, 获奖年份: 2015
班级名称:初三二班,学生名称:诸葛亮, 性别:男, 获奖年份: 2012
班级名称:初三二班,学生名称:赵云, 性别:男, 获奖年份: 2012
班级名称:初三二班,学生名称:赵云, 性别:男, 获奖年份: 2015
班级名称:初三二班,学生名称:许诸, 性别:男, 获奖年份: 2012
班级名称:初三二班,学生名称:黄盖, 性别:男, 获奖年份: 2015
班级名称:初三二班,学生名称:貂婵, 性别:女, 获奖年份: 2018
班级名称:初三二班,学生名称:刘小勇, 性别:男, 获奖年份: 2018
班级名称:初三二班,学生名称:李宇春, 性别:人妖, 获奖年份: 2018

[集合操作] 取百米跑的记录
刘备,男,18,[2010,2014,2015],[百米跑,唱歌,跳远]
许诸,男,18,[2008,2009,2010,2011,2012],[百米跑,跳远,百米跑,唱歌,百米跑]
许诸,男,18,[2008,2009,2010,2011,2012],[百米跑,跳远,百米跑,唱歌,百米跑]
许诸,男,18,[2008,2009,2010,2011,2012],[百米跑,跳远,百米跑,唱歌,百米跑]
赵云,男,17,[2009,2012,2015],[跳绳,跳远,百米跑]
诸葛亮,男,16,[2008,2009,2010,2011,2012],[数字竞赛,作文竞赛,唱歌,唱歌,百米跑]

[集合操作] 取百米跑,唱歌的交集记录
刘备,男,18,[2010,2014,2015],[百米跑,唱歌,跳远]
许诸,男,18,[2008,2009,2010,2011,2012],[百米跑,跳远,百米跑,唱歌,百米跑]
诸葛亮,男,16,[2008,2009,2010,2011,2012],[数字竞赛,作文竞赛,唱歌,唱歌,百米跑]

[ZIP操作] 把两个相关的序列合并成一个
李宇春,人妖
黄盖,男
刘小勇,男

[分区操作] 用于数据分页
page=1
符大乔,12,女
张飞,13,男
李香兰,13,女
曹操,15,男
诸葛亮,16,男

page=2
赵云,17,男
周瑜,17,男
刘备,18,男
许诸,18,男
貂婵,18,女

page=3
李宇春,21,人妖
黄盖,22,男
刘小勇,28,男


[转换] ToList()会立即执行查询,ToLookUp()用于创建一对多的键值对
刘备
张飞
符大乔
李香兰
曹操
诸葛亮
诸葛亮
许诸
貂婵
貂婵
貂婵
刘小勇
刘小勇
刘小勇
李宇春
李宇春
李宇春
李宇春

===========================================

并行LINQ结束,耗时:805

===========================================

..........................................................................................................................................................................................................................................................................................................................................................................................
[非并行] 查找文档中包含a的字符串, 耗时: 38 秒
........................................................................................................................................................................................................................................................................................................................................................
[并行] 查找文档中包含a的字符串, 耗时: 35 秒
.................................................................................................................................................................................................................................................................
[非并行] 计算short类型所有数字的和, 耗时: 25 秒
.......................................................................................................................................................................................................................................................................
[并行] 计算short类型所有数字的和, 耗时: 26 秒
.......................................................................................................................................
[并行] 查找与排序(AsOrdered), 耗时: 13 秒
..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
[并行] 查找与排序(orderby), 耗时: 55 秒
..............................
 测试完成.

===========================================



开始载入150万条记录.

[并行] 载入150万条记录完毕, 耗时: 2372 

[非并行] 查找记录中年龄在20到25的记录, 耗时: 138 

[并行] 查找记录中年龄在20到25的记录, 耗时: 150 

计算完成.


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

作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864