답변:
Collection<T>
주위에 사용자 정의 가능한 래퍼 IList<T>
입니다. 동안 IList<T>
밀폐되지 않은, 어떤 사용자 정의 포인트를 제공하지 않습니다. Collection<T>
의 메서드는 기본적으로 표준 IList<T>
메서드에 위임 되지만 원하는 작업을 수행하도록 쉽게 재정의 할 수 있습니다. Collection<T>
IList로 할 수 있다고 생각하지 않는 이벤트를 내부에 연결하는 것도 가능합니다 .
요컨대, 사실 이후에 확장하는 것이 훨씬 쉬우므로 잠재적으로 리팩토링이 훨씬 줄어들 수 있습니다.
IList
, IList<T>
, List<T>
등 한마디로 말하면, 당신이 그것을 호출할지 여부를 모른다. 다형성이이를 수정합니다.
ObservableCollection<T>
변경 사항에 대해 알리기 위해 메서드가 재정의되는 예제로 답변에 추가 할 수 있습니다 .
C #에는 개체 모음을 나타내는 세 가지 개념이 있습니다. 기능 증가 순서는 다음과 같습니다.
Enumerable 에는 순서가 없습니다. 세트에서 항목을 추가하거나 제거 할 수 없습니다. 세트의 항목 수를 얻을 수도 없습니다. 세트의 각 항목에 차례로 액세스 할 수 있습니다.
수집 은 수정 가능한 집합입니다. 세트에서 객체를 추가 및 제거 할 수 있으며 세트의 항목 수를 가져올 수도 있습니다. 그러나 여전히 순서가없고 순서가 없기 때문에 인덱스로 항목에 액세스 할 수없고 정렬 할 방법도 없습니다.
목록 은 정렬 된 개체 집합입니다. 목록을 정렬하고, 인덱스로 항목에 액세스하고, 인덱스로 항목을 제거 할 수 있습니다.
실제로 이러한 인터페이스를 살펴보면 서로를 기반으로 구축됩니다.
interface IEnumerable<T>
GetEnumeration<T>
interface ICollection<T> : IEnumerable<T>
Add
Remove
Clear
Count
interface IList<T> = ICollection<T>
Insert
IndexOf
RemoveAt
변수 또는 메소드 매개 변수를 선언 할 때 다음을 사용하도록 선택해야합니다.
개념적으로는 개체 집합을 처리해야합니다.
목록의 모든 개체에 대해 무언가를 수행 할 수 있어야한다면 다음 만 필요합니다 IEnumerable
.
void SaveEveryUser(IEnumerable<User> users)
{
for User u in users
...
}
[사용자가에 보관하는 경우 상관 없어 List<T>
, Collection<T>
, Array<T>
다른 사람 또는 아무것도. 당신은IEnumerable<T>
인터페이스 .
세트에서 항목을 추가, 제거 또는 계산할 수 있어야하는 경우 컬렉션 을 사용하십시오 .
ICollection<User> users = new Collection<User>();
users.Add(new User());
정렬 순서에 관심이 있고 올바른 순서가 필요한 경우 List 를 사용하십시오 .
IList<User> users = FetchUsers(db);
차트 형식 :
| Feature | IEnumerable<T> | ICollection<T> | IList<T> |
|------------------------|----------------|----------------|----------|
| Enumerating items | X | X | X |
| | | | |
| Adding items | | X | X |
| Removing items | | X | X |
| Count of items | | X | X |
| | | | |
| Accessing by index | | | X |
| Removing by indexx | | | X |
| Getting index of item | | | X |
List<T>
과 Collection<T>
에서 System.Collections.Generic
이 인터페이스를 구현하는 두 개의 클래스가 있습니다; 그러나 그들은 유일한 수업이 아닙니다.
ConcurrentBag<T>
주문한 개체 가방입니다 ( IEnumerable<T>
).LinkedList<T>
색인 ( ICollection
)으로 항목에 액세스 할 수없는 가방입니다 . 하지만 컬렉션에서 항목을 임의로 추가 및 제거 할 수 있습니다.SynchronizedCollection<T>
인덱스별로 항목을 추가 / 제거 할 수있는 정렬 된 컬렉션따라서 다음을 쉽게 변경할 수 있습니다.
IEnumerable<User> users = new SynchronizedCollection<User>();
SaveEveryUser(users);
선택 개념 당신이 필요를, 다음 일치하는 클래스를 사용합니다.
ICollection<T>
및 IList<T>
. 다른 구체적인 구현은 다르게 동작 할 수 있습니다. 예를 들어 인터페이스를 List<T>
통해에 액세스하는 경우 IEnumerable<T>
목록에서 항목을 추가, 제거, 정렬 또는 계산할 방법이 없습니다.
List<T>
응용 프로그램 코드 내에서 내부적으로 사용하기위한 것입니다. 수락하거나 반환하는 공개 API를 작성하지 않아야합니다.List<T>
(대신 수퍼 클래스 또는 컬렉션 인터페이스 사용을 고려하십시오).
Collection<T>
사용자 지정 컬렉션에 대한 기본 클래스를 제공합니다 (직접 사용할 수 있음).
Collection<T>
특정 기능이없는 경우 코드에서 사용 을 고려하십시오.List<T>
필요한 .
위는 단지 권장 사항입니다.
[출처 : 프레임 워크 디자인 지침, 제 2 판]
Dictionary<string, List<string>>
를 반환하는 List<string>
것은 괜찮습니다. 딕셔너리의 상태 는 그 내용이 아니라 그 안에있는 목록 의 신원 만을 캡슐화 하기 때문입니다.
List<T>
매우 다재다능하기 때문에 매우 일반적으로 사용되는 컨테이너입니다 ( Sort
,Find
하지만 당신은 행동의 오버라이드 (override) 할 경우 (삽입에 대한 검사 항목을 예를 들어) 더 확장 지점이 없습니다 -, 등).
Collection<T>
는 IList<T>
(기본값은 List<T>
) 주위의 래퍼입니다 . 확장 점 ( virtual
메소드)이 있지만 Find
. 간접적이므로.보다 약간 느리지 List<T>
만 그다지 많지는 않습니다.
LINQ와에 여분의 방법 List<T>
부터 덜 중요 해지고, 어쨌든을 제공하는 경향이있다 -에 - 객체 LINQ ... 예를 들어 First(pred)
, OrderBy(...)
등
목록이 더 빠릅니다.
예를 들어
private void button1_Click(object sender, EventArgs e)
{
Collection<long> c = new Collection<long>();
Stopwatch s = new Stopwatch();
s.Start();
for (long i = 0; i <= 10000000; i++)
{
c.Add(i);
}
s.Stop();
MessageBox.Show("collect " + s.ElapsedMilliseconds.ToString());
List<long> l = new List<long>();
Stopwatch s2 = new Stopwatch();
s2.Start();
for (long i = 0; i <= 10000000; i++)
{
l.Add(i);
}
s2.Stop();
MessageBox.Show("lis " + s2.ElapsedMilliseconds.ToString());
}
내 컴퓨터 List<>
에서 거의 두 배 빠릅니다.
편집하다
사람들이 왜 이것을 반대하는지 이해할 수 없습니다. 직장 컴퓨터와 가정용 컴퓨터 모두 List <> 코드가 80 % 더 빠릅니다.
HanselmanCollection<T>
은 다음과 같이 말합니다. " 목록처럼 보이며 List<T>
내부적으로도 있습니다. 모든 단일 메서드는 내부에 위임합니다 List<T>
. 여기에는 List<T>
.
편집 : Collection<T>
System.Generic.Collections .NET 3.5에 존재하지 않습니다. .NET 2.0에서 3.5로 마이그레이션하는 경우 Collection<T>
명백한 것이 누락되지 않는 한 많은 개체를 사용하는 경우 일부 코드를 변경해야합니다 .
편집 2 : Collection<T>
이제 .NET 3.5의 System.Collections.ObjectModel 네임 스페이스에 있습니다. 도움말 파일은 다음과 같이 말합니다.
"System.Collections.ObjectModel 네임 스페이스에는 재사용 가능한 라이브러리의 개체 모델에서 컬렉션으로 사용할 수있는 클래스가 포함되어 있습니다. 속성 또는 메서드가 컬렉션을 반환 할 때 이러한 클래스를 사용하십시오."
이러한 모든 인터페이스는에서 상속하므로 IEnumerable
이해해야합니다. 이 인터페이스를 사용하면 기본적으로 foreach 문 (C #)에서 클래스를 사용할 수 있습니다.
ICollection
나열한 인터페이스 중 가장 기본적인 인터페이스입니다. 를 지원하는 열거 가능한 인터페이스 Count
이며 그게 전부입니다.IList
모든 ICollection
것이지만 항목 추가 및 제거, 인덱스로 항목 검색 등도 지원합니다. "객체 목록"에 가장 일반적으로 사용되는 인터페이스입니다.IQueryable
LINQ를 지원하는 열거 가능한 인터페이스입니다. 항상 IQueryable
IList에서을 만들고 LINQ to Objects를 사용할 수 있지만 IQueryable
LINQ to SQL 및 LINQ to Entities에서 SQL 문의 지연된 실행 에도 사용됩니다.IDictionary
고유 한 키를 값에 매핑한다는 점에서 다른 동물입니다. 또한 키 / 값 쌍을 열거 할 수 있다는 점에서 열거 할 수 있지만 그렇지 않으면 나열한 다른 목적과 다른 용도로 사용됩니다.MSDN에 따르면 List (Of T) .Add는 "an O (n) operation"( "Capacity"가 초과 된 경우)이고 Collection (Of T) .Add는 항상 "an O (1) operation"입니다. List가 Array 및 Collection a Linked List를 사용하여 구현되면 이해할 수 있습니다. 그러나 그 경우라면 Collection (Of T) .Item이 "an O (n) operation"이 될 것으로 예상합니다. 하지만- 아니야 !?! Collection (Of T) .Item은 List (Of T) .Item과 마찬가지로 "O (1) 작업"입니다.
그 위에 "tuinstoel"의 "Dec 29 '08 at 22:31"게시물은 위의 클레임 속도 테스트에서 List (Of T)를 보여줍니다 .Add to be faster than Collection (Of T) .Add that I'veproduced with Long과 String. MSDN에 따르면 그의 주장 80 %에 비해 33 % 더 빨라졌지만 "n"번은 그 반대 였어야합니다!?!
둘 다 동일한 인터페이스를 구현하므로 동일한 방식으로 작동합니다. 내부적으로 다르게 구현 될 수 있지만 테스트를 거쳐야합니다.
내가 보는 유일한 차이점은 네임 스페이스와 Collection<T>
으로 표시된 사실 ComVisibleAttribute(false)
이므로 COM 코드에서 사용할 수 없습니다.
다른 asnwers 외에도 일반 목록 및 수집 기능에 대한 간략한 개요를 편집했습니다. 컬렉션은 목록의 제한된 하위 집합입니다.
* = 현재
o = 부분적으로 존재
속성 / 메소드 컬렉션 < T > 목록 < T > --------------------------------------- -------
Add() * *
AddRange() *
AsReadOnly() *
BinarySearch() *
Capacity *
Clear() * *
Contains() * *
ConvertAll() *
CopyTo() o *
Count * *
Equals() * *
Exists() *
Find() *
FindAll() *
FindIndex() *
FindLast() *
FindLastIndex() *
ForEach() *
GetEnumerator() * *
GetHashCode() * *
GetRange() *
GetType() * *
IndexOf() o *
Insert() * *
InsertRange() *
Item() * *
LastIndexOf() *
New() o *
ReferenceEquals() * *
Remove() * *
RemoveAll() *
RemoveAt() * *
RemoveRange() *
Reverse() *
Sort() *
ToArray() *
ToString() * *
TrimExcess() *
TrueForAll() *