C#编程之IList<T>、List<T>、ArrayList、IList, ICollection、IEnumerable、IEnumerator、IQueryable 和 IEnumerable的区别

额。。。今天看了半天Ilist<T>和List<T>的区别,然后惊奇的发现使用IList<T>还是List<T>对我的项目来说没有区别。。。
 在C#中,数组、ArrayList都能够存储一组对象,那么三者到底有什么样的区别呢?

数组

数组在C#中最早出现的。在内存中是连续的,所以它的索引速度非常快,而且赋值与修改元素也很简单。
  1. string[] s=new string[2];  
  2.   
  3. //赋值  
  4. s[0]="a";  
  5. s[1]="b";  
  6. //修改  
  7. s[1]="a1";  
string[] s=new string[2];

//赋值
s[0]="a";
s[1]="b";
//修改
s[1]="a1";
        但是数组存在一些不足的地方。在数组的两个数据间插入数据是非常麻烦的,而且在声明数组的时候必须指定数组的长度,数组的长度过长会造成内存浪费,过短会造成数据溢出。如果在声明数组时我们不清楚数组的长度就会很麻烦。

ArrayList

        针对数组的这些缺点,C#中最先提供了ArrayList对象来解决这些问题。
        ArrayList是命名空间System.Collections下的一部分,在使用该类时必须进行引用,同时继承了IList接口,提供了数据存储和检索。ArrayList对象的大小是按照存储的数据来动态扩充与收缩的。所以在声明ArrayList对象时并不需要指定它的长度。
  1. ArrayList list1 = new ArrayList();  
  2.   
  3. //新增数据  
  4. list1.Add("cde");  
  5. list1.Add(5678);  
  6.   
  7. //修改数据  
  8. list[2] = 34;  
  9.   
  10. //移除数据  
  11. list.RemoveAt(0);  
  12.   
  13. //插入数据  
  14. list.Insert(0, "qwe");  
ArrayList list1 = new ArrayList();

//新增数据
list1.Add("cde");
list1.Add(5678);

//修改数据
list[2] = 34;

//移除数据
list.RemoveAt(0);

//插入数据
list.Insert(0, "qwe");
       从上面的例子看,ArrayList好像解决了数组中所有的缺点,为什么又会有List?
       我们从上面的例子看,在List中,我们不仅插入了字符串cde,而且插入了数字5678。这样在ArrayList中插入不同类型的数据是允许的。因为ArrayList会把插入其中的数据当object类型来处理,在我们使用ArrayList处理数据时,很可能会报类型不匹配的错误,也就是ArrayList不是类型安全的。在存储或检索值类型时通常发生装箱和取消装箱的操作,带来很大的性能损耗。
       装箱与拆箱的概念:
       简单的说:
       装箱:就是将值类型的数据打包到引用类型的实例中
       比如将string类型的值赋值abc赋给object对象obj
  1. String  i=”abc”;  
  2. object obj=(object)i;  
String  i=”abc”;
object obj=(object)i;
       拆箱:就是从引用数据中提取值类型
       比如将object对象obj的值赋值给string类型的变量i
  1. object obj=”abc”;  
  2. string i=(string)obj;  
object obj=”abc”;
string i=(string)obj;
       装箱与拆箱的操作是非常耗性能的。

泛型List

       因为ArrayList存在不安全类型与装箱拆箱的缺点,所以出现了泛型的概念。List类是ArrayList类的泛型等效类,它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内的对象类型。
  1. List<string> list = new List<string>();  
  2.   
  3. //新增数据  
  4. list.Add(“abc”);  
  5.   
  6. //修改数据  
  7. list[0] = “def”;  
  8.   
  9. //移除数据  
  10. list.RemoveAt(0);  
List<string> list = new List<string>();

//新增数据
list.Add(“abc”);

//修改数据
list[0] = “def”;

//移除数据
list.RemoveAt(0);
上例中如果我们往List集合中插入int数组123,IDE就会报错,且不能通过编译。这样就避免了前面讲的类型安全问题与装箱拆箱的性能问题了。

总结

      数组的容量是固定的,只能一次获取或设置一个元素的值,而ArrayList或List<T>的容量可根据需要自动扩充、修改、删除、或插入数据。
      数组可以具有多个维度,而ArrayhuoList<T>始终只有一个维度。但是,可以轻松的创建数组列表或列表的列表。特定类型(Object除外)的数组的性能优于ArrayList的性能。这事因为ArrayList的元素属于Object类型;所以在存储或检索值类型时通常发生装箱和拆箱的操作。不过,在不需要重新分配时(即最初容量十分接近列表的最大容量),List<T>的性能与同类型的数组十分相近。
      在决定使用List<T>还是使用ArrayList类(两者具有相似的功能)时,记住List<T>类在大多数情况下执行的更好并且是类型安全的。如果对List<T>类的类型T使用引用类型,则两个类的行为是完全相同的。但是,如果对类型T使用值类型,则需要考虑实现和装箱的问题。
 

出处:https://blog.csdn.net/finish_dream/article/details/51627904

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

  IList, ICollection ,IEnumerable 很显然,这些都是集合接口的定义,先看看定义:

    // 摘要:
    //     表示可按照索引单独访问的对象的非泛型集合。
    [ComVisible(true)]
    public interface IList : ICollection, IEnumerable
    {
        // 摘要:
        //     获取一个值,该值指示 System.Collections.IList 是否具有固定大小。
        //
        // 返回结果:
        //     如果 System.Collections.IList 具有固定大小,则为 true;否则为 false。
        bool IsFixedSize { get; }
        //
        // 摘要:
        //     获取一个值,该值指示 System.Collections.IList 是否为只读。
        //
        // 返回结果:
        //     如果 System.Collections.IList 为只读,则为 true;否则为 false。
        bool IsReadOnly { get; }

        // 摘要:
        //     获取或设置指定索引处的元素。
        //
        // 参数:
        //   index:
        //     要获得或设置的元素从零开始的索引。
        //
        // 返回结果:
        //     指定索引处的元素。
        //
        // 异常:
        //   System.ArgumentOutOfRangeException:
        //     index 不是 System.Collections.IList 中的有效索引。
        //
        //   System.NotSupportedException:
        //     设置该属性,而且 System.Collections.IList 为只读。
        object this[int index] { get; set; }

        // 摘要:
        //     向 System.Collections.IList 中添加项。
        //
        // 参数:
        //   value:
        //     要添加到 System.Collections.IList 的对象。
        //
        // 返回结果:
        //     新元素所插入到的位置,或为 -1 以指示未将该项插入到集合中。
        //
        // 异常:
        //   System.NotSupportedException:
        //     System.Collections.IList 是只读的。- 或 -System.Collections.IList 具有固定大小。
        int Add(object value);
        //
        // 摘要:
        //     从 System.Collections.IList 中移除所有项。
        //
        // 异常:
        //   System.NotSupportedException:
        //     System.Collections.IList 是只读的。
        void Clear();
        //
        // 摘要:
        //     确定 System.Collections.IList 是否包含特定值。
        //
        // 参数:
        //   value:
        //     要在 System.Collections.IList 中查找的对象。
        //
        // 返回结果:
        //     如果在 System.Collections.IList 中找到 System.Object,则为 true;否则为 false。
        bool Contains(object value);
        //
        // 摘要:
        //     确定 System.Collections.IList 中特定项的索引。
        //
        // 参数:
        //   value:
        //     要在 System.Collections.IList 中查找的对象。
        //
        // 返回结果:
        //     如果在列表中找到 value,则为该项的索引;否则为 -1。
        int IndexOf(object value);
        //
        // 摘要:
        //     在 System.Collections.IList 中的指定索引处插入项。
        //
        // 参数:
        //   index:
        //     从零开始的索引,应在该位置插入 value。
        //
        //   value:
        //     要插入到 System.Collections.IList 中的对象。
        //
        // 异常:
        //   System.ArgumentOutOfRangeException:
        //     index 不是 System.Collections.IList 中的有效索引。
        //
        //   System.NotSupportedException:
        //     System.Collections.IList 是只读的。- 或 -System.Collections.IList 具有固定大小。
        //
        //   System.NullReferenceException:
        //     value 在 System.Collections.IList 中是 null 引用。
        void Insert(int index, object value);
        //
        // 摘要:
        //     从 System.Collections.IList 中移除特定对象的第一个匹配项。
        //
        // 参数:
        //   value:
        //     要从 System.Collections.IList 中移除的对象。
        //
        // 异常:
        //   System.NotSupportedException:
        //     System.Collections.IList 是只读的。- 或 -System.Collections.IList 具有固定大小。
        void Remove(object value);
        //
        // 摘要:
        //     移除指定索引处的 System.Collections.IList 项。
        //
        // 参数:
        //   index:
        //     从零开始的索引(属于要移除的项)。
        //
        // 异常:
        //   System.ArgumentOutOfRangeException:
        //     index 不是 System.Collections.IList 中的有效索引。
        //
        //   System.NotSupportedException:
        //     System.Collections.IList 是只读的。- 或 -System.Collections.IList 具有固定大小。
        void RemoveAt(int index);
    }
View Code
    // 摘要:
    //     定义所有非泛型集合的大小、枚举器和同步方法。
    [ComVisible(true)]
    public interface ICollection : IEnumerable
    {
        // 摘要:
        //     获取 System.Collections.ICollection 中包含的元素数。
        //
        // 返回结果:
        //     System.Collections.ICollection 中包含的元素数。
        int Count { get; }
        //
        // 摘要:
        //     获取一个值,该值指示是否同步对 System.Collections.ICollection 的访问(线程安全)。
        //
        // 返回结果:
        //     如果对 System.Collections.ICollection 的访问是同步的(线程安全),则为 true;否则为 false。
        bool IsSynchronized { get; }
        //
        // 摘要:
        //     获取一个可用于同步对 System.Collections.ICollection 的访问的对象。
        //
        // 返回结果:
        //     可用于同步对 System.Collections.ICollection 的访问的对象。
        object SyncRoot { get; }

        // 摘要:
        //     从特定的 System.Array 索引处开始,将 System.Collections.ICollection 的元素复制到一个 System.Array
        //     中。
        //
        // 参数:
        //   array:
        //     作为从 System.Collections.ICollection 复制的元素的目标位置的一维 System.Array。System.Array
        //     必须具有从零开始的索引。
        //
        //   index:
        //     array 中从零开始的索引,将在此处开始复制。
        //
        // 异常:
        //   System.ArgumentNullException:
        //     array 为 null。
        //
        //   System.ArgumentOutOfRangeException:
        //     index 小于零。
        //
        //   System.ArgumentException:
        //     array 是多维的。- 或 -源 System.Collections.ICollection 中的元素数目大于从 index 到目标 array
        //     末尾之间的可用空间。
        //
        //   System.ArgumentException:
        //     源 System.Collections.ICollection 的类型无法自动转换为目标 array 的类型。
        void CopyTo(Array array, int index);
    }
View Code

    // 摘要:
    //     公开枚举器,该枚举器支持在非泛型集合上进行简单迭代。
    [ComVisible(true)]
    [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
    public interface IEnumerable
    {
        // 摘要:
        //     返回一个循环访问集合的枚举器。
        //
        // 返回结果:
        //     可用于循环访问集合的 System.Collections.IEnumerator 对象。
        [DispId(-4)]
        IEnumerator GetEnumerator();
    }
View Code

 可以看出,所有集合接口的祖宗是IEnumerable

     此接口只有一个方法 GetEnumerator()。是为了实现迭代器模式设计的接口。所有继承了IEnumerable的类,要使用foreach迭代器时,就需要使用该方法。因此也只有实现了该接口的类才可以使用foreach。


     ICollection继承自IEnumerable,IList继承自ICollection

     这两个接口都是为了给集合提供一些公用的方法。只是分了两个层次,IList比ICollection多几个方法,增加,移除成员。可以简单理解为:ICollection主要针对静态集合;IList主要针对动态集合。

      IList 是 ICollection 接口的子代,并且是所有非泛型列表的基接口。IList 实现有三种类别:只读、固定大小和可变大小。无法修改只读 IList。固定大小的 IList 不允许添加或移除元素,但允许修改现有元素。可变大小的 IList 允许添加、移除和修改元素 (IList中的 IsFixedSize { get; }  和  bool IsReadOnly { get; })


  IList,ICollection,IEnumerable 在命名空间System.Collections中。

      关于System.Collections空间

      System.Collections命名空间包含可使用的集合类和相关的接口,提供了集合的基本功能。     

   该命名空间下的.NET非泛型集合类如下所示:

      — System.Collections.ArrayList:数组集合类,使用大小可按动态增加的数组实现Ilist接口。 
      — System.Collections.BitArray:布尔集合类,管理位值的压缩数组,该值为布尔值。
      — System.Collections.Queue:队列,表示对象的先进先出集合。
      — System.Collections.Stack:堆栈,表示对象的简单的后进先出集合。
      — System.Collections.Hashtable:哈希表,表示键/值对的集合,这些键/值对根据键的哈希代码进行组织
      — System.Collections.SortedList:排序集合类,表示键/值对的集合,这些键和值按键排序并可按键和索引访问。

    该命名空间下的.NET非泛型接口如下所示:

      — System.Collections.ICollection:(继承于IEnumerable)定义所有集合的大小,枚举器和同步方法,可以获取集合中项的个数,并能把项复制到一个简单的数组类型中。
      — System.Collections.IComparer:比较两个对象的方法
      — System.Collections.IList:(继承于IEnumerable 和 ICollection)表示可按照索引单独访问一组对象,提供集合的项列表,并可以访问这些项。
      — System.Collections.IDictionary:(继承于IEnumerable 和 ICollection)表示键/值对的集合
      — System.Collections.IDictionaryEnumerator:枚举字典的元素
      — System.Collections.IEnumerator:支持在集合上进行简单迭代,可以迭代集合中的项。支持在非泛型集合进行简单迭代。


  IList<T>,ICollection<T>,IEnumerable<T> 在System.Collections.Generic 命名空间中。     

                System.Collections.Generic是.net中的泛型集合 

    IList<T>,ICollection<T>,IEnumerable<T> 是2.0引入泛型以后新增的。主要是提高重用性与类型安全。
  IEnumerable<T>继承自IEnumerable,ICollection<T>继承自IEnumerable<T>,List<T>继承自ICollection<T>
  因此可以完全使用泛型接口,而放弃使用ICollection和IList。泛型接口提供了更好的类型安全和编译时的检验。
      补充:  IEnumerable<T>和IEnumerable都只有一个方法。ICollection<T>和ICollection的结构是不一样的。ICollection<T>比ICollection多几个方法。它包含了几个IList中的几个方法。也许是对以前的改进。

 

    IEnumerable 和 IEnumerator

 IEnumerator

      如果一个类实现了IEnumerator,也就是实现Current属性,MoveNext方法,Reset方法。只要实现这些方法,这个类就可以用foreach这种语法了。 

      IEnumerable接口主要实现了GetEnumerator方法,该方法返回一个IEnumerator。一个类实现IEnumerable接口后,调用foreach语法的时候,会自动的调用GetEnumerator方法,然后在这个IEnumerator中遍历。  所以只要实现两者之中任意一个接口,就可以用foreach语法了。但是本质上都是对IEnumerator做foreach,只是一个是直接,一个是间接。

      代码说明:

  比如类Test,实现了IEnumerable,那么下面的代码

    foreach (Test  t  in ts)

    {     ... } 

  说明代码就功能上等同于下面的代码

    IEnumerator td= ts.GetEnumerator(); 

    while (td.MoveNext()) 

    {     

      t = (Foo)td.Current()    

      ...  

    }   

    如果一个类,同时实现了IEnumerator<T>,IEnumerable<T>,那么就是糟糕的设计 因为用foreach语法的时候,会先调用IEnumerable的GetEnumerator方法。

 

 

  IList<T> 和List<T>

  首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口。
  它仅仅是所有泛型类型的接口,并没有太多方法可以方便实用,如果仅仅是作为集合数据的承载体,确实,IList可以胜任。
  不过,更多的时候,我们要对集合数据进行处理,从中筛选数据或者排序。这个时候IList就爱莫能助了。
  1、当你只想使用接口的方法时,ILis<>这种方式比较好.他不获取实现这个接口的类的其他方法和字段,有效的节省空间.(既然子类是继承父类的子类又有自己的属性和方法,那么子类NEW出来后这些都应该有而且必须有的,不论放在父类的变量里面还是自身类型的变量里面,不然的话向上转型后再向下转型数据就会丢失喽,太可怕了!)
  2、IList <>是个接口,定义了一些操作方法这些方法要你自己去实现,List <>是泛型类,它已经实现了IList <>定义的那些方法
  IList ilist=new List ();
  List list=new List ();
  这两行代码,从操作上来看,实际上都是创建了一个List对象的实例,也就是说,他们的操作没有区别。
  只是用于保存这个操作的返回值变量类型不一样而已。
  那么,我们可以这么理解,这两行代码的目的不一样。
  List List11 =new List ();
  是想创建一个List,而且需要使用到List的功能,进行相关操作。
  而IList IList11 =new List ();
  只是想创建一个基于接口IList的对象的实例,只是这个接口是由List实现的。所以它只是希望使用到IList接口规定的功能而已。

 

  如果一个方法的返回值是IEnumerable<T> ,必须在方法后面使用.ToList()方法才能得到一个集合数据

     List<XElement> grandchildElements = xlsElement.XPathSelectElements("//model").ToList();

  使用.ToArray()方法,就会创建一个数组数据

    XElement[] elements = xlsElement.Descendants(nodeName).ToArray();

  集合数据要用foreach来遍历,而数组数据可以使用下标操作。

 

出处:https://blog.csdn.net/superhoy/article/details/20908739

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

楼主最近看了下

IQueryable 和 IEnumerable

的区别。

当真被忽悠的死去活来。。。

网上都说 IQueryable 和 IEnumerable区别很大,然后怎么着怎么着。。。可怜

然后我就去测试了啊

先拿出我的数据库表结构。

这里是我的查询语句。比较简单

  1. TestDataEntities db = new TestDataEntities();  
  2.             IQueryable<Orders> q = db.Orders.OrderBy(x=>x.id).Skip(1).Take(2);  
  3.             IEnumerable<Orders> e = db.Orders.OrderBy(x=>x.id).Skip(1).Take(2);  
  4.   
  5.             Console.WriteLine("IQueryable :  "+q.ToString());  
  6.             Console.WriteLine("---------------------------------------------------------");  
  7.             Console.WriteLine("IEnumerable :  " + e.ToString());  
TestDataEntities db = new TestDataEntities();
            IQueryable<Orders> q = db.Orders.OrderBy(x=>x.id).Skip(1).Take(2);
            IEnumerable<Orders> e = db.Orders.OrderBy(x=>x.id).Skip(1).Take(2);

            Console.WriteLine("IQueryable : 
"+q.ToString());
            Console.WriteLine("---------------------------------------------------------");
            Console.WriteLine("IEnumerable : 
" + e.ToString());

输出结果:

IQueryable :

  1. SELECT TOP (2)   
  2. [Extent1].[id] AS [id],   
  3. [Extent1].[parentid] AS [parentid],   
  4. [Extent1].[code] AS [code]  
  5. FROM ( SELECT [Extent1].[id] AS [id], [Extent1].[parentid] AS [parentid], [Extent1].[code] AS [code], row_number() OVER (ORDER BY [Extent1].[id] ASCAS [row_number]  
  6.     FROM [dbo].[Orders] AS [Extent1]  
  7. )  AS [Extent1]  
  8. WHERE [Extent1].[row_number] > 1  
  9. ORDER BY [Extent1].[id] ASC  
SELECT TOP (2) 
[Extent1].[id] AS [id], 
[Extent1].[parentid] AS [parentid], 
[Extent1].[code] AS [code]
FROM ( SELECT [Extent1].[id] AS [id], [Extent1].[parentid] AS [parentid], [Extent1].[code] AS [code], row_number() OVER (ORDER BY [Extent1].[id] ASC) AS [row_number]
	FROM [dbo].[Orders] AS [Extent1]
)  AS [Extent1]
WHERE [Extent1].[row_number] > 1
ORDER BY [Extent1].[id] ASC



IEnumerable :

  1. SELECT TOP (2)   
  2. [Extent1].[id] AS [id],   
  3. [Extent1].[parentid] AS [parentid],   
  4. [Extent1].[code] AS [code]  
  5. FROM ( SELECT [Extent1].[id] AS [id], [Extent1].[parentid] AS [parentid], [Extent1].[code] AS [code], row_number() OVER (ORDER BY [Extent1].[id] ASCAS [row_number]  
  6.     FROM [dbo].[Orders] AS [Extent1]  
  7. )  AS [Extent1]  
  8. WHERE [Extent1].[row_number] > 1  
  9. ORDER BY [Extent1].[id] ASC  
SELECT TOP (2) 
[Extent1].[id] AS [id], 
[Extent1].[parentid] AS [parentid], 
[Extent1].[code] AS [code]
FROM ( SELECT [Extent1].[id] AS [id], [Extent1].[parentid] AS [parentid], [Extent1].[code] AS [code], row_number() OVER (ORDER BY [Extent1].[id] ASC) AS [row_number]
	FROM [dbo].[Orders] AS [Extent1]
)  AS [Extent1]
WHERE [Extent1].[row_number] > 1
ORDER BY [Extent1].[id] ASC

有区别吗?没有哇!!!

后来楼主就较真了!!!!!!是的,较真了!!!为何网上这么多人说有区别!发火发火发火发火

然后发现。。。。是这个原因!~

看楼下代码

  1. TestDataEntities db = new TestDataEntities();  
  2.             IQueryable<Orders> q = db.Orders.OrderBy(x => x.id).AsQueryable<Orders>().Skip(10).Take(2);  
  3.             IEnumerable<Orders> e = db.Orders.OrderBy(x => x.id).AsEnumerable<Orders>().Skip(10).Take(2);  
  4.   
  5.             foreach (var item in q)  
  6.             {  
  7.                 Console.WriteLine("123");  
  8.             }  
  9.   
  10.             foreach (var item in e)  
  11.             {  
  12.                 Console.WriteLine("234");  
  13.             }  
TestDataEntities db = new TestDataEntities();
            IQueryable<Orders> q = db.Orders.OrderBy(x => x.id).AsQueryable<Orders>().Skip(10).Take(2);
            IEnumerable<Orders> e = db.Orders.OrderBy(x => x.id).AsEnumerable<Orders>().Skip(10).Take(2);

            foreach (var item in q)
            {
                Console.WriteLine("123");
            }

            foreach (var item in e)
            {
                Console.WriteLine("234");
            }

原因其实出在

AsQueryable 和 AsEnumerable  

反正就是加载方式不同

上面代码的sql语句是这样的!

IQueryable :

  1. SELECT TOP (2)   
  2. [Extent1].[id] AS [id],   
  3. [Extent1].[parentid] AS [parentid],   
  4. [Extent1].[code] AS [code]  
  5. FROM ( SELECT [Extent1].[id] AS [id], [Extent1].[parentid] AS [parentid], [Extent1].[code] AS [code], row_number() OVER (ORDER BY [Extent1].[id] ASCAS [row_number]  
  6. FROM [dbo].[Orders] AS [Extent1]  
  7. )  AS [Extent1]  
  8. WHERE [Extent1].[row_number] > 10  
  9. ORDER BY [Extent1].[id] ASC  
SELECT TOP (2) 
[Extent1].[id] AS [id], 
[Extent1].[parentid] AS [parentid], 
[Extent1].[code] AS [code]
FROM ( SELECT [Extent1].[id] AS [id], [Extent1].[parentid] AS [parentid], [Extent1].[code] AS [code], row_number() OVER (ORDER BY [Extent1].[id] ASC) AS [row_number]
FROM [dbo].[Orders] AS [Extent1]
)  AS [Extent1]
WHERE [Extent1].[row_number] > 10
ORDER BY [Extent1].[id] ASC



IEnumerable :

  1. SELECT   
  2. [Extent1].[id] AS [id],   
  3. [Extent1].[parentid] AS [parentid],   
  4. [Extent1].[code] AS [code]  
  5. FROM [dbo].[Orders] AS [Extent1]  
  6. ORDER BY [Extent1].[id] ASC  
SELECT 
[Extent1].[id] AS [id], 
[Extent1].[parentid] AS [parentid], 
[Extent1].[code] AS [code]
FROM [dbo].[Orders] AS [Extent1]
ORDER BY [Extent1].[id] ASC
是的,你没看错,奇怪在于IEnumerable生成的语句,是查询全表。

聪明的你肯定会联想到。IEnumerable是通过缓存全表,然后才分页查找的!!!所以IEnumerable性能不好!

为什么????!!!!

因为:

IQueryable     是 linq to sql           这家伙操作数据库

IEnumerable 是  linq to object     这家伙操作内存

区别在这里!

当然网上还有说IQueryable 和 IEnumerable其他区别(这个楼主没有验证)

IEnumerable<T>查询必须在本地执行.并且执行查询前我们必须把所有的数据加载到本地

 

总结一下:

IQueryable     是 linq to sql         这家伙操作数据库

IEnumerable 是  linq to object     这家伙操作内存

IEnumerable 会查询全部数据,然后在内存里进行分页或者筛选操作。

但是真正导致他们使用哪种方式的,是AsQueryable() 和 AsEnumerable()  !!!!!

出处:https://blog.csdn.net/hanjun0612/article/details/50070081

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

原文地址:https://www.cnblogs.com/mq0036/p/9189427.html