浅谈IEnumerator、IEnumerable、IQueryable

IEnumerator是所有枚举数的基接口,继承此接口的类型通过实现MoveNext,Current,Reset方法实现迭代器。
IEnumerable是任何Collection集合实现foreach遍历都要继承的接口(主要是实现其中返回类型为IEnumerator的GetEnumerator方法)
IQueryable和IEnumerable都具有延迟加载的功能,IEnumerable主要运用于本地数据集,常用于Linq to object,而IQuerable多用于远程数据集,常用于Linq to Sql。
下面动手实现不继承IEnumerable而支持实现foreach的类

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

namespace ForeachDemo
{
    public class PersonEnumerable
    {
        private string[] strList;
        public PersonEnumerable(string[] _strList)
        {
            strList = _strList;
        }
        public IEnumerator GetEnumerator()
        {
            //return new Person(strList);
            for (int i = 0; i < strList.Length; i++)
            {
                yield return strList[i];
            }
        }
    }
}

main方法

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

namespace ForeachDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] person = {"wen","jin","lei" };
            PersonEnumerable personEnumable = new PersonEnumerable(person);

foreach (var item in personEnumable)
{
	Console.WriteLine(item);
}

Console.ReadLine();
       }
    }
}

这里其实是用了yield关键字来实现了IEnumerator的Current、MoveNext、Reset方法,可以用ILSPY查看反编译后的代码,所以说要想一个类可通过foreach实现遍历,并不一定要继承IEnumerable接口,只要实现GetEnumerator()方法就好。

再来说说IEnumerable和IQueryable的区别

public void LinqTest()  
03.       {  
04.           var db = new SecurityRepositoryContext(new HSLogger());  
05.           var ur = new UserRepository(db);  
07.           IQueryable<User> querys = (from c in db.Context.Set<User>()  
08.                                      orderby c.Code  
09.                                      select c).Skip<User>(2).Take<User>(2);  
10.           //注意这个AsEnumerable<User>()在分页查询之前,先将其转换成IEnumerable类型  
11.           IEnumerable<User> enumers = (from c in db.Context.Set<User>()  
12.                                        orderby c.Code  
13.                                        select c).AsEnumerable<User>().Skip<User>(2).Take<User>(2);  
14.           //因为启用了延迟加载机制,所以下面调用一下,才会真正去读取数据库  
15.           foreach (var c in querys)  
16.           {  
17.               //TODO  
18.           }  
19.           foreach (var c in enumers)  
20.           {   
21.               //TODO  
22.           }  
23.       }  

类型为IQueryable 的querys 实际上并没有去数据库取值,而是在执行foreach时,才会把skip和take编译成sql中的条件去数据库中取值,这样的好处是不用把所有的结果集都加载到内存中后再去筛选符合条件的数据。

类型为IEnumerable的enumers 同样也是在做foreach时去数据库取值,不同的是,它是将所有的数据全部加载到内存后再去通过委托去筛选符合条件的数据。
继承了IQueryable的类实现的扩展方法如Where、select等接受的参数都是表达式树,而IEnumerable接受的是委托

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值