为什么在许多/一对多的关系中使用ICollection而不是IEnumerable或List <T>?

Jan*_*ray 342 c# entity-framework icollection code-first

我在教程中看到了很多,导航属性为ICollection<T>.

这是实体框架的强制性要求吗?我可以用IEnumerable吗?

使用ICollection代替IEnumerable甚至是什么的主要目的是List<T>什么?

Tra*_*s J 419

通常您选择的内容取决于您需要访问的方法.一般而言 - IEnumerable<>(MSDN:http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx)获取只需要迭代的对象列表,ICollection<>(MSDN:http:// msdn.microsoft.com/en-us/library/92t2ye13.aspx)获取需要迭代和修改List<>的对象列表,以获取需要迭代,修改,排序等的对象列表(请参阅此处有关完整列表:http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx).

从更具体的角度来看,延迟加载可以选择类型.默认情况下,实体框架中的导航属性带有更改跟踪并且是代理.为了将动态代理创建为导航属性,必须实现虚拟类型ICollection.

表示关系的"多"端的导航属性必须返回实现ICollection的类型,其中T是关系另一端的对象的类型.- 创建POCO代理MSDN的要求

有关定义和管理关系MSDN的详细信息

  • @TravisJ:`List <T>`有一个`GetEnumerator()`方法,与`IEnumerable <T>`的实现分开,它返回一个可变结构类型`List <T> .Enumerator`.在大多数情况下,与独立堆对象相比,该类型的性能稍好一些.鸭子类型枚举器(作为C#和vb.net都可以)的编译器在生成`foreach`代码时可以利用这一点.如果在`foreach`之前将`List <T>`强制转换为`IEnumrable <T>`,则`IEnumerable <T> .GetEnumerator()`方法将返回堆分配的对象,从而无法进行优化. (13认同)
  • 那么,有了这个,`List` 应该会好很多,是吗? (3认同)
  • @JanCarloViray - 我倾向于使用`List`.虽然它具有最大的开销,但它提供了最多的功能. (3认同)
  • 关于编辑,将属性限制为接口类型不是关于内存,而是关于封装.考虑:`private IEnumerable <int> _integers = new List <int> {1,2,3};`使用与`private List <int> _integers = new List <int> {1,2,3}相同的内存; ` (2认同)

Jus*_*ner 79

ICollection<T>之所以使用,是因为IEnumerable<T>界面无法添加项目,删除项目或以其他方式修改集合.

  • `List <T>`实现`ICollection <T>`. (12认同)
  • 非泛型“ICollection”不允许以任何方式添加项目,但它仍然是“IEnumerable&lt;T&gt;”的有用辅助,因为它提供了“Count”成员,该成员通常比枚举所有内容快得多。请注意,如果将“IList&lt;Cat&gt;”或“ICollection&lt;Cat&gt;”传递给需要“IEnumerable&lt;Animal&gt;”的代码,则“Count()”扩展方法将很快(如果它实现了非通用的“ICollection”) `,但如果它仅实现通用接口,则不会,因为典型的 `ICollection&lt;Cat&gt;` 不会实现 `ICollection&lt;Animal&gt;`。 (4认同)
  • 与List &lt;T&gt;进行比较呢? (2认同)

pho*_*oog 58

回答您的问题List<T>:

List<T>是一个班级; 指定接口允许更灵活的实现.一个更好的问题是"为什么不IList<T>呢?"

要回答这个问题,请考虑IList<T>增加的内容ICollection<T>:整数索引,这意味着项目具有一些任意顺序,并且可以通过引用该顺序来检索.在大多数情况下,这可能没有意义,因为可能需要在不同的上下文中对项目进行不同的排序.


Ram*_*nan 18

ICollection和IEnumerable之间存在一些基本的区别

  • IEnumerable - 仅包含GetEnumerator方法以获取Enumerator并进行循环
  • ICollection包含以下方法 - 添加/删除/包含/计数/复制到
  • ICollection继承自IEnumerable
  • 使用ICollection,您可以使用add/remove等方法修改集合,您无权使用IEnumerable执行相同的操作.

简单程序:

using System;
using System.Collections;
using System.Collections.Generic;

namespace StackDemo
{
    class Program 
    {
        static void Main(string[] args)
        {
            List<Person> persons = new List<Person>();
            persons.Add(new Person("John",30));
            persons.Add(new Person("Jack", 27));

            ICollection<Person> personCollection = persons;
            IEnumerable<Person> personEnumeration = persons;

            //IEnumeration
            //IEnumration Contains only GetEnumerator method to get Enumerator and make a looping
            foreach (Person p in personEnumeration)
            {                                   
               Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
            }

            //ICollection
            //ICollection Add/Remove/Contains/Count/CopyTo
            //ICollection is inherited from IEnumerable
            personCollection.Add(new Person("Tim", 10));

            foreach (Person p in personCollection)
            {
                Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);        
            }
            Console.ReadLine();

        }
    }

    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Person(string name,int age)
        {
            this.Name = name;
            this.Age = age;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 12

我记得这样:

  1. IEnumerable有一个方法GetEnumerator(),它允许读取集合中的值但不写入它.使用枚举器的大部分复杂性由C#中的每个语句为我们处理.IEnumerable有一个属性:Current,它返回当前元素.

  2. ICollection实现了IEnumerable并添加了一些额外的属性,其中最常用的是Count.ICollection的通用版本实现了Add()和Remove()方法.

  3. IList实现IEnumerable和ICollection,并添加对项的整数索引访问(通常不需要,因为在数据库中完成排序).

  • 基于你写的ICollection和IList是一样的.请添加ICollection中不存在的添加到IList的内容. (4认同)

Tig*_*ran 7

使用的基本思想ICollection是提供一个接口来只读访问一些有限数量的数据.实际上你有一个ICollection.Count属性.IEnumerable更适合于您读取到某个逻辑点的某些数据链,某些条件由消费者明确指定或直到枚举结束.

  • TIL [ICollection`](http://msdn.microsoft.com/en-us/library/System.Collections.ICollection%28v=vs.110%29.aspx)是只读的,而``ICollection <T >`(http://msdn.microsoft.com/en-us/library/c28hx0c4%28v=vs.110%29.aspx)不是. (14认同)