The Sixth Assignment

今天我们来学习一下LINQ这个神奇的东西。。。还有LINQ相关的一些玩意。。
根据度娘的说法:
LINQ,语言集成查询(Language Integrated Query)是一组用于c#Visual Basic语言的扩展。
它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。
LINQ定义了大约40个查询操作符,如select、from、in、where以及order by
LINQ 提供了一条更常规的途径即给.Net Framework添加一些可以应用于所有信息源的具有多种用途的语法查询特性
这是比向开发语言和运行时添加一些关系数据特性或者类似 XML 特性更好的方式。
这些语法特性就叫做 .NET Language Integrated Query (LINQ)
 
首先来学习一下LINQ相关的东西
 
1) from 临时变量 in 实现IEnumerable<T>接口的对象
IEnumerable和IEnumerable<T>接口在.NET中是非常重要的接口,它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代。
IEnumerable和IEnumerable<T>接口是.NET Framework中最基本的集合访问器。
来看一段代码
using System;
using System.Collections.Generic;
using System.Linq;                
using System.Text;
namespace IEnumeratorSample
{
    class Person                                    //定义一个Person类
    {
        public string Name;                         //定义Person的名字
        public string Age;                          //定义Person的年龄
        public Person(string name, string age)      //为Person初始化(构造函数)
        {
            Name = name;                            //配置Name值
            Age = age;                              //配置Age值
        }
    }
}
上述代码定义了一个Person类并抽象一个Person类的属性,这些属性包括Name和Age。Name和Age属性分别用于描述Person的名字和年龄,用于数据初始化。
初始化之后的数据就需要创建一系列Person对象,通过这些对象的相应属性能够进行对象的访问和遍历,示例代码如下所示。
  class Program
  {
static void Main(string[] args) { Person[] per = new Person[2] //创建并初始化2个Person对象 { new Person("guojing","21"), //通过构造函数构造对象 new Person("muqing","21"), //通过构造函数构造对象 }; foreach (Person p in per) //遍历对象 Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age); Console.ReadKey(); }
  }
上述代码创建并初始化了2个Person对象,并通过foreach语法进行对象的遍历。
但是上述代码是在数组中进行查询的,就是说如果要创建多个对象,则必须创建一个对象的数组,如上述代码中的Per变量,而如果需要直接对对象的集合进行查询,却不能够实现查询功能。
例如增加一个构造函数,该构造函数用户构造一组Person对象,示例代码如下所示。
     private Person[] per;
        public Person(Person[] array)                          //重载构造函数,迭代对象
        {
            per = new Person[array.Length];                    //创建对象
            for (int i = 0; i < array.Length; i++)             //遍历初始化对象
            {
                per[i] = array[i];                             //数组赋值
            }
        }
上述构造函数动态的构造了一组People类的对象,那么应该也能够使用foreach语句进行遍历,示例代码如下所示。
           
       Person personlist = new Person(per);                              //创建对象
           foreach (Person p in personlist)                                  //遍历对象
           {
                Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);
           }
在上述代码的foreach语句中,直接在Person类的集合中进行查询,系统则会报错“ConsoleApplication1.Person”不包含“GetEnumerator”的公共定义,
因此foreach语句不能作用于“ConsoleApplication1.Person”类型的变量,因为Person类并不支持foreach语句进行遍历。
为了让相应的类能够支持foreach语句执行遍历操作,则需要实现派生自类IEnumerable并实现IEnumerable接口,示例代码如下所示。
  public IEnumerator GetEnumerator()                                                                //实现接口
    {
        return new GetEnum(_people);
    }
为了让自定义类型能够支持foreach语句,则必须对Person类的构造函数进行编写并实现接口,示例代码如下所示。
   
   class Person:IEnumerable                          //派生自IEnumerable,同样定义一个Personl类
    {
        public string Name;                                                       
        public string Age;                                                       
        public Person(string name, string age)                                   
        {
            Name = name;                                                            
            Age = age;                                                                
        }
        public IEnumerator GetEnumerator()                             
        {
            return new PersonEnum(per);                                  
        }
}
上述代码重构了Person类并实现了接口,接口实现的  class PersonEnum : IEnumerator                                            
    {
    public Person[] _per;                                                                 
    int position = -1;                                 
    public PersonEnum(Person[] list)
    {
        _per = list;                                                          
    }
    public bool MoveNext()                               //实现向前移动
    {
        position++;                                      //位置增加
        return (position < _per.Length);                 //返回布尔值
    }
    public void Reset()                                  //位置重置
    {
        position = -1;                                   //重置指针为-1
   } public object Current  { get {   return _per[position];         }
   }
上述代码实现了foreach语句的功能,当开发Person类初始化后就可以直接使用Personal类对象的集合进行LINQ查询,示例代码如下所示。
     static void Main(string[] args)
        {
            Person[] per = new Person[2]                                   
            {
                new Person("guojing","21"),                           
                new Person("muqing","21"),                          

            };
            Person personlist = new Person(per);                    
            foreach (Person p in personlist)                              
                Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);
            Console.ReadKey();
        }
实例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace IEnumeratorSample
{
    class Person : IEnumerable
    {
        public string Name;
        public string Age;
        public Person(string name, string age)
        {
            Name = name;
            Age = age;
        }
        private Person[] per;
        public Person(Person[] array)
        {
            per = new Person[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                per[i] = array[i];
            }
        }
        public IEnumerator GetEnumerator()
        {
            return new PersonEnum(per);
        }
    }
    class PersonEnum : IEnumerator
    {
        public Person[] _per;
        int position = -1;
        public PersonEnum(Person[] list)
        {
            _per = list;
        }
        public bool MoveNext()
        {
            position++;
            return (position < _per.Length);
        }
 
        public void Reset()
        {
            position = -1;
        }
        public object Current
        {
            get
            {return _per[position];
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Person[] per = new Person[2]
            {
                new Person("guojing","21"),
                new Person("muqing","21"),
            };
            Person personlist = new Person(per);
            foreach (Person p in personlist)//遍历对象
            {
                Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);
            }
            Console.ReadKey();
        }
    }
}

2) 实现IEnumerable<T>接口的对象.LINQ方法名(lambda表达式)。
 lambda运算符:所有的lambda表达式都是用新的lambda运算符 " => ",可以叫他,“转到”或者 “成为”。
        运算符将表达式分为两部分,左边指定输入参数,右边是lambda的主体。
        lambda表达式:
               1.一个参数:param=>expr
               2.多个参数:(param-list)=>expr

来看一段代码
namespace lambda
{
    public class Person
    {
        public string Name { get; set; }
        public int Age  {  get;set; }    
    }
    class Program
    {

        public static List<Person> PersonsList()
        {
            List<Person> persons = new List<Person>();
            for (int i = 0; i < 7; i++)
            {
                Person p = new Person() { Name = i + "儿子", Age = 8 - i, };
                persons.Add(p);                
            }
            return persons;
        }
        static void Main(string[] args)
        {
       List<Person> persons = PersonsList();
       var person6 = persons.Where(p => p.Age > 6).ToList(); //所有Age>6的Person的集合
       System.Console.WriteLine("Age>6);
       foreach (Person p in person6)
          System.Console.WriteLine("Name is" + p.Name + " Age is" + p.Age);

Person per1 = persons.SingleOrDefault(p => p.Age == 1); //Age=1的单个people类
System.Console.WriteLine("Age=1");
if (per1 == null)
System.Console.WriteLine("不存在");
else
System.Console.WriteLine("Name is" + per1.Name + " Age is" + per1.Age);

            Person per2 = persons.SingleOrDefault(p => p.Age == 1);     //Age=2的单个people类
System.Console.WriteLine("Age=2");
if (per2 == null)
System.Console.WriteLine("不存在");
else
System.Console.WriteLine("Name is" + per2.Name + " Age is" + per2.Age); System.Console.WriteLine("Contain 儿子");
            var personerzi = persons.Where(p => p.Name.Contains("儿子")).ToList();   //所有Name包含儿子的Person的集合
foreach (Person p in personerzi)
System.Console.WriteLine("Name is" + p.Name + " Age is" + p.
     }
  }
}


好了,了解完这些就可以进入正题了
先看一段代码
namespace ConsoleApplication3
{
    class IntroToLINQ
    {
        static void Main()
        {
            // The Three Parts of a LINQ Query:
            //  1. Data source.
            int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

            // 2. Query creation.
            // numQuery is an IEnumerable<int>
            var numQuery =
                from num in numbers
                where (num % 2) == 0
                select num;

            // 3. Query execution.
            foreach (int num in numQuery)
            {
                Console.Write("{0} ", num);
            }
        }
    }
}
在这里LINQ的基本表达方式为
var numQuery = from num in numbers
                where (num % 2) == 0
                select num;

基本上和sql语句没有什么差别..只是select要放在最后...

而上述代码的运行结果如下



 
原文地址:https://www.cnblogs.com/tiny-home/p/4460843.html