Linq与where实现查询(Linq to Entity)【IEnumerable与IEnumerator与IList】|自己实现foreach的功能

110 篇文章 2 订阅

<自己实现foreach的功能,其实也就是foreach的原理>  新建了一个控制台应用程序

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

namespace foreach原理
{

    public class Person:IEnumerable
    {
        //想要遍历这个数组就需要实现IEnumerable的接口,实现这个接口的目的就是让当前类型中增加一个名字为GetEnumerator()的方法(其实我们仅仅是需要我们当前类型中有GetEnumerator()这么么一个方法,与它实现不实现IEnumerable这个接口没有半毛钱关系,那我们直接在当前类里定义这么一个方法不就行了吗?为什么还要去实现这个IEnumerable接口?答案是:为了方便,大家都这么做,所以我们就这么做。)
        private string[] Friends = new string[] { "张三", "李四", "王五", "赵六" };

        /// <summary>
        /// GetEnumerator()方法的作用就是获取一个枚举器,拿到了枚举器就可以实现遍历了。
        /// </summary>
        /// <returns></returns>
        public IEnumerator GetEnumerator()
        {
            //那这个方法中我们该写什么代码呢??? 我观察这个方法,知道它需要返回一个IEnumerator类型,既然它需要返回一个IEnumerator类型,所以我们就要给它返回一个IEnumerator这个接口的一个子类对象。那我们现在也没有这个IEnumerator接口的子类对象,怎么办呢? 答案是:我们直接写一个吧!

            return new MyPersonEnumerator(this.Friends); //new一个MyPersonEnumerator类对象,顺便传递了当前类的Friends数组 给新new出来的对象来初始化
        }
    }

    /// <summary>
    /// MyPersonEnumerator类实现了IEnumerator接口,它就变成了一个枚举器
    /// </summary>
    public class MyPersonEnumerator : IEnumerator
    {
        private string[] _friends;
        public MyPersonEnumerator(string [] str) //你要枚举(遍历)什么数据,只要通过这个方法把要遍历的数据传过来,就可以了
        {
            _friends = str;
        }

        //定义个下标(一般情况下,下标都是一开始指向了第一条数据的前一条,而第一条数据的下标是0)
        private int index = -1;


        //那我们来实现以下IEnumerator这个接口。 这个接口下面有三个方法
        /// <summary>
        /// 当前对象
        /// </summary>
        public object Current 
        {
            get
            { 
                if(index>=0 && index<_friends.Length)
                {
                    return _friends[index];
                }
                else
                {
                     throw new  IndexOutOfRangeException();
                }
            }
        }
        /// <summary>
        /// 向后移动的一条数据
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            //当用户调用MoveNext()方法的时候,就应该让下标自增一下
            if (index < _friends.Length-1)
            {
                index++;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 重置到一开始的位置
        /// </summary>
        public void Reset()
        {
            //当用户手动调用Reset()方法的时候就给下标重置为-1 (如果不重置,下次用户想在遍历数据的时候,此时的下标就不是从-1,所以就没有办法从第一条数据开始遍历了。)
            index = -1;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person();
            IEnumerator ie = p.GetEnumerator();//得到一个枚举器

            while (ie.MoveNext()) //只要往后移动成功
            {
               string s=  ie.Current.ToString(); //获取当前对象,

               Console.WriteLine(s); //打印出当前对象 :打印出:张三 李四 王五 赵六
            }

            ie.Reset(); //遍历完后,将枚举器下标还原到第一条数据的前面。这样的话下面的遍历又可以继续了。

            while (ie.MoveNext()) 
            {
                string s = ie.Current.ToString(); 

                Console.WriteLine(s); 
            }

            Console.ReadKey();
        }
    }
}

<1>=============================================

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

namespace linq
{
    class Student
    {
        public string Name { get; set; }
        public string Language { get; set; }
        public string Position { get; set; }

        public Student()
        { 
            
        }
    }
    class Program
    {
        //IEnumerator与IEnumerable与Ilist与list的区别:IEnumerator其实就是一个迭代器,而当一个类继承了IEnumerable接口的时候,就会实现IEnumerable接口里面的唯一一个抽象方法GetEnumerator(),只要实现这个方法,那么我们就可以使用这个迭代器了。即可以使用foreach
        //IList接口是继承了IEnumerator接口,IList接口在IEnumerator接口上扩展了一些方法,所以IList方法功能更多,而list类又是继承了Ilist接口并实现了接口中的方法的,并在Ilist接口的基础上又扩展了一些方法。所以list类的功能更多。但是我们在使用这些IEnumerable,IList和list的时候最好是按照实际情况来用,节约资源。list功能太多,很多时候我们用不到它那么多的功能,如果不需要的话,会造成资源浪费,牺牲性能了。


        //LINQ语法一 LINQ即语言集成查询,是.NET Framework 3.5中新增的功能。其功能类似于数据库中的SQL语句(实际上LINQ就是针对.NET Framework的SQL):提供标准的、易于学习的查询和更新数据模式。
        //从from开始用过SQL的朋友都知道,最简单的SQL语句SELECT record FROM tableName:获取表中的所有记录,那么对应于LINQ,其语法如下:
        //from record in tableName select record。
        //明显的差异是将from语句放到了句首,此种语法方式只是为了适应Visual Studio中智能提示(试想如果将from子句放在后面,先输入select语句,此时select的对象类型尚不确定,智能提示无法做出相应提示)

        //SQL语句是从数据库表中查询出记录,而LINQ适应的数据源更广,包括SQL Server数据库、XML文档、ADO.NET数据集以及所有支持IEnumerable及IEnumerable<T>接口的任意对象集合。

        //LINQ只是一种语法,LINQ查询语句实际上和我们常用的foreach语句相似:中间语言(IL)中并没有对应的foreach语句,编译器最终会将foreach语句转换为一些列的语句块,例如: 

        static void Main(string[] args)
        {
                       
            string[] str = { "Id", "Age", "Name" ,"Name2"};
            foreach (string s in str)
            {
                Console.WriteLine(s);
            }

            //转换为↓↓↓
            IEnumerator e = str.GetEnumerator(); //实现这个方法后,就可以使用foeach语句遍历这个e对象了


            //其实IEnumerable接口是非常的简单,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnumerator对象

            //GetEnumerator()方法是IEnumerable接口里的一个抽象方法,它返回一个可用于循环访问集合的IEnumerator对象;
            
            //一个集合要支持Foreach语句,必须实现接口IEnumerable接口,即必须实现IEnumerable接口的GetEnumerator方法
            

            //任何集合类对象都有一个GetEnumerator()方法,该方法可以返回一个实现了 IEnumerator接口的对象,这个返回的IEnumerator对象既不是集合类对象,也不是集合的元素类对象,它是一个独立的类对象。通过这个对象,可以遍历访问集合类对象中的每一个元素对象。
            
        
            

            //在创建枚举数之后或在调用 Reset 方法后,枚举数放置在集合的第一个元素之前,首次调用 MoveNext 方法会将枚举数移到集合的第一个元素。如果 MoveNext 越过集合的末尾,则枚举数将放置在集合中最后一个元素的后面,而且 MoveNext 返回 false。 当枚举数位于此位置时,在调用 Reset 之前,对 MoveNext 的后续调用也返回 false。  注:Reset方法是将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
            while (e.MoveNext())
            {
                Console.WriteLine(e.Current); //Current是获取集合中的当前元素。词条语句和上面的foreach语句效果一样
            }




//===================================下面才是真正的Linq语句与where==============================================

            //在.NET Framework 3.5中为IEnumerable<T>接口加入了大量的扩展方法,这些方法为LINQ提供了实现基础(就像IEnumerable中GetEnumerator方法为foreach提供实现基础一样)
            //例如,IEnumerable中的Where扩展方法,它和LINQ中的where子句对应,用于筛选数据:

            //-----------------------------使用Where方法------------------

            IEnumerable<string> query = str.Where(s => s.StartsWith("N"));
            foreach (string s in query)
            {
                Console.WriteLine(s);
            }

            //------------------------------使用query语句-------------------

            IEnumerable<string> query1 = from ss in str
                  where ss.StartsWith("N")
                  select ss;

            
            foreach (string i in query1)
            {
                Console.WriteLine(i);
            }
            
            //**********************************************************------示例1------**********************

            Student stt = new Student() { Name = "钱掌柜", Language = "数学", Position = "七侠镇" };

            //创建一个Student类型的数组,里面放置的是Student对象
            Student[] stu=new Student[]
            {   
               
                new Student{Name="张三",Language="c#",Position="Leader"},
                new Student{Name="李四",Language="c#",Position="Coder"},
                new Student{Name="王五",Language="java",Position="Coder"}
            
            
            };

           
            //-----------------------linq语句实现----------遍历stu数---------------------
            var queryPs = from s in stu
                          //where条件筛选,指定条件,选出Language为c#的对象
                          where s.Language == "c#"
                          select new { Name = s.Name, Position = s.Position };

            foreach (var ss in queryPs)
            {
                Console.WriteLine(String.Format("Name:{0}\t\tPosition:{1}", ss.Name,  ss.Position));

            }

            //------------------------------------------用where条件实现---------------------
            IEnumerable<Student> queryLL = stu.Where(s => s.Language.StartsWith("c#"));
            foreach (var v in queryLL)
            {
                Console.WriteLine("Name:{0}\t\tPosition:{1}", v.Name,  v.Position);
            }



            



            //**********************************************************------示例2------**********************

            string[] strings = { "dfdf", "b", "c123", "d" };
            
            var queryS = from s in strings
                        where s.StartsWith("c")
                        select s;
            foreach (string s in queryS)
            {
                Console.WriteLine(s);
            }

            //var vv = typeof(Type).GetProperties();
            //foreach (var vvv in vv)
            //{
            //    Console.WriteLine(vvv.Name);
            //}


            var sss = new { age = 25,Name="tom" };
            string name = sss.Name;
            Console.WriteLine(name);
            var type1 = sss.GetType();
            Console.WriteLine(type1.Name);
            Console.ReadKey();
        }
    }
}


<2>

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

namespace LinqToEntity
{
    class Program
    {
        static void Main(string[] args)
        {
            //点击项目右键-添加->新建项->ADO.NET实体数据模型,然后..选择你需要的表,点击完成。这里我选择是数据库是sales表的名字是xs,默认生成了一个实体容器名称 salesEntities
            
            salesEntities salesEn = new salesEntities();

            //用拉姆的表达式来查询实体中的数据
           // var temp = salesEn.xs;
            var query = salesEn.xs.Where(s => s.总学分>50);
            foreach (var v in query)
            {
                Console.WriteLine(v.姓名);
            }

            Console.WriteLine();

            //用Linq来查询实体中的数据
            var temp2 = from x in salesEn.xs
                        where x.总学分 > 50
                        select x;
            
            foreach (var v in temp2)
            {
                Console.WriteLine(v.姓名+v.学号+" "+v.姓别);
            }
            Console.ReadKey();            
            
        }
    }
}


<2>

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

namespace 拉姆达表达式
{

    class Program
    {
        static void Main(string[] args)
        {
            //-------------------------------------------------------使用Where方法

            List<int> list = new List<int> { 1, 7, 8, 15, 95, 2, 5, 32 };
            Program p = new Program();

            var mylist = list.Where(s => s > 15);//筛选出list中大于15的元素 

            foreach(var v in mylist) //遍历mylist
            {
                Console.WriteLine(v); //输出95,32
            }

            //------------------------------------------------------使用query语句

            var query = from s in list
                        where s > 15
                        select s;

            foreach (var v in query) //遍历query
            {
                Console.WriteLine(v); //输出95,32
            }

            Console.ReadKey();
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值