Why use ICollection and not IEnumerable or List

2019-01-02 21:27发布

I see this a lot in tutorials, with navigation properties as ICollection<T>.

Is this a mandatory requirement for Entity Framework? Can I use IEnumerable?

What's the main purpose of using ICollection instead of IEnumerable or even List<T>?

8条回答
啃猪蹄的小仙女
2楼-- · 2019-01-02 22:00

There are some basics difference between ICollection and IEnumerable

  • IEnumerable - Contains only GetEnumerator method to get Enumerator and make a looping
  • ICollection is containing the following methods - Add/Remove/Contains/Count/CopyTo
  • ICollection is inherited from IEnumerable
  • With ICollection you can modified the collection by using the methods like add/remove , you dont have the liberty to do the same with IEnumerable.

Simple Program:

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;
        }
    }
}
查看更多
Viruses.
3楼-- · 2019-01-02 22:02

What I have done in the past is declare my inner class collections using IList<Class>, ICollection<Class>or IEnumerable<Class> (if static list) depending on whether or not I will have to do any number of the following in a method in my repository: enumerate, sort/order or modify. When I just need to enumerate (and maybe sort) over objects then I create a temp List<Class>to work with the collection within an IEnumerable method. I think this practice would only be effective if the collection is relatively small, but it may be good practice in general, idk. Please correct me if there is evidence as to why this would not good practice.

查看更多
\"骚年 ilove
4楼-- · 2019-01-02 22:06

Usually what you choose will depend on which methods you need access to. In general

IEnumerable<>:

According to MSDN documentation

IEnumerable<> for a list of objects that only needs to be iterated through.

ICollection<>:

According to MSDN documentation

ICollection<> for a list of objects that needs to be iterated through and modified.

List<>:

According to MSDN documentation

List<> for a list of objects that needs to be iterated through, modified, sorted, etc.

From a more specific standpoint, lazy loading comes in to play with choosing the type. By default, navigation properties in Entity Framework come with change tracking and are proxies. In order for the dynamic proxy to be created as a navigation property, the virtual type must implement ICollection.

A navigation property that represents the "many" end of a relationship must return a type that implements ICollection, where T is the type of the object at the other end of the relationship. -Requirements for Creating POCO ProxiesMSDN

More information on Defining and Managing RelationshipsMSDN

查看更多
Fickle 薄情
5楼-- · 2019-01-02 22:17

Responding to your question about List<T>:

List<T> is a class; specifying an interface allows more flexibility of implementation. A better question is "why not IList<T>?"

To answer that question, consider what IList<T> adds to ICollection<T>: integer indexing, which means the items have some arbitrary order, and can be retrieved by reference to that order. This is probably not meaningful in most cases, since items probably need to be ordered differently in different contexts.

查看更多
女痞
6楼-- · 2019-01-02 22:17

The basic idea of using ICollection is a provide an interface to readonly-access to some finite amount of data. In fact you have a ICollection.Count property. IEnumerable is more suitable for some chain of the data where you read till some logical point, some condition esplicitly specified by consumer or till the end of the enumeration.

查看更多
Explosion°爆炸
7楼-- · 2019-01-02 22:19

ICollection<T> is used because the IEnumerable<T> interface provides no way of adding items, removing items, or otherwise modifying the collection.

查看更多
登录 后发表回答