C #에서 다양한 Collection 제네릭 인터페이스의 차이점


11

나는 Windows 용 C #과 ASP.net MVC 개발을 한동안 가지고 놀았습니다. 그러나 나는 여전히 몇몇 영역에서 불분명하다. 비슷한 종류의 Generic Collection Interfaces 를 사용하고 교환 할 때의 성능 문제와 기본적인 차이점을 이해하려고합니다 .

사이의 기본적인 차이는 무엇인가 IEnumerable<T>, ICollection<T>, List<T>(Class)?

내 응용 프로그램에서 아무런 문제도 보지 않고 사용하고 교환하는 것 같습니다. 또한이 세 가지와 교환 할 수있는 이와 유사한 일반 컬렉션이 있습니까?


2
IList <T>도 있습니다
jk.

답변:


19

List <T> 는 클래스이며 ICollection <T>IEnumerable <T> 인터페이스를 모두 구현합니다 . 또한 ICollection <T>는 IEnumerable <T> 인터페이스를 확장합니다. 그것들은 적어도 모든 관점에서 교환 가능한 것은 아닙니다.

List <T>가있는 경우이 개체는 ICollection <T> 및 IEnumerable <T> 인터페이스에서 구현하는 데 필요한 메서드와 속성을 구현해야합니다. 컴파일러는이를 알고 있으며이를 "내재적으로"ICollection <T> 또는 IEnumerable <T>로 캐스트 할 수 있습니다. 당신은 ICollection이있는 경우, <T> 당신은 목록 <T> 또는 뭔가 다른 첫번째 여부를 코드에서 명시 적으로 확인해야합니다, 아마도 사전 <T> (T는 어디 KeyValuePair 당신이 무엇을 캐스팅 전) 욕구.

ICollection은 IEnumerable을 확장하므로 IEnumerable로 캐스트 할 수 있습니다. 그러나 IEnumerable 만있는 경우 다시 목록이라는 보장이 없습니다. 그럴 수도 있지만 다른 것일 수도 있습니다. 예를 들어 List <T>를 Dictionary <T>로 캐스트하려는 경우 유효하지 않은 캐스트 예외가 예상됩니다.

따라서 "교환 할 수있는"것은 아닙니다.

또한 많은 일반 인터페이스가 있으므로 System.Collections.Generic 네임 스페이스 에서 무엇을 찾을 수 있는지 확인하십시오 .

편집 : 귀하의 의견과 관련하여 List <T> 또는 구현하는 인터페이스 중 하나를 사용하면 성능 저하가 전혀 없습니다. 여전히 새 객체를 만들어야합니다. 다음 코드를 확인하십시오.

List<T> list = new List<T>();
ICollection<T> myColl = list;
IEnumerable<T> myEnum = list;

list , myCollmyEnum은 모두 동일한 객체를 가리 킵니다. List 또는 ICollection 또는 IEnumerable로 선언하든 여전히 List를 만들려면 프로그램이 필요합니다. 나는 이것을 쓸 수 있었다 :

ICollection<T> myColl = new List<T>();

MYCOLL은 , 런타임에 여전히 목록입니다.

그러나 이것이 가장 중요한 점입니다. 커플 링을 줄이고 유지 관리 성높이 려면 인터페이스 또는 추상 클래스 또는 구체적 클래스인지 여부에 관계없이 변수와 메서드 매개 변수를 가능한 한 가장 작은 분모로 선언해야합니다.

"PerformOperation"메소드에 필요한 유일한 요소는 요소를 열거하고, 일부 작업을 수행하고 종료하는 것입니다.이 경우 List <T>에서 사용 가능한 수백 개의 메소드가 필요하지 않으며 IEnumerable <T에서 사용 가능한 것만 필요합니다. >, 따라서 다음이 적용되어야합니다.

public void PerformOperation(IEnumerable<T> myEnumeration) { ... }

그렇게하면 사용자와 다른 개발자는 IEnumerable <T> 인터페이스를 구현하는 클래스의 모든 개체가이 메서드에 제공 될 수 있음을 알 수 있습니다. 다른 개발자가 작성한 목록, 사전 또는 사용자 정의 콜렉션 클래스 일 수 있습니다.

반대로 명시 적으로 구체적 List <T>가 필요하다고 지정하면 (실제로는 드물게 발생하지만 여전히 발생할 수 있음) 귀하와 다른 개발자는 이것이 List 또는 다른 구체적인 클래스를 상속해야 함을 알고 있습니다 목록에서.


우선 감사합니다. 이제 중요한 점은 사용할 것을 결정하는 방법입니다. List <T>는 두 인터페이스를 모두 구현하므로 IEnumerable 또는 ICollection이 필요한 모든 장소에서 항상 사용하지 않는 것이 좋습니다. 항상 목록을 사용하면 성능에 영향을 미칩니 까? 이러한 우려에 대한 답변을 작성하려면 답변을 편집하십시오
Pankaj Upadhyay

공연 질문에 답변하기 위해 편집
Jalayn

+1이지만, 실제로 목록을 메소드에 전달해야하는 드문 경우에는 메소드 선언이 IList아니라 사용해야합니다 List.
Konamiman

@Konamiman- List<>과 같은 특정 기능 이 필요한지 여부에 따라 다릅니다 .AddRange(). 는 IList<>그 노출되지 않습니다.
밥슨

6

ICollectionIEnumerable에 대한 MSDN 페이지를 살펴보십시오 .

매우 추상적 인 용어로, 이것이 내가 이러한 유형을 생각하는 방법입니다.

IEnumerable은 열거 할 수있는 모든 것, 즉 반복됩니다. 반드시 '수집'을 의미하지는 않습니다. 예를 들어 IQueryable 은 IEnumerable을 구현하며 컬렉션은 아니지만 개체를 ​​반환하기 위해 쿼리 할 수있는 항목입니다. IEnumerable을 구현하려면 쿼리 할 때 개체 만 개체를 ​​반환 할 수 있어야합니다. 나는 오늘 할 일을 열거 할 수 있다고 말할 수 있습니다 (목록을 작성하거나 공식화하지 않았기 때문에 목록이 아니지만 지금 할 일을 말할 수는 있습니다. 당신이 '그리고 그때?'

ICollection은 IEnumerable보다 구체적입니다. 중요한 차이점은 Collection에 포함 된 항목 수를 알고 있다는 것입니다. 열거 형에 몇 개의 항목이 있는지 알아 내려면 효과적으로 반복하고 계산합니다.

나 : 얘들 아, 얼마나 많은 아이템을 가지고 있니?

열거 가능 : 나는 정말로 모른다. 글쎄, 여기 하나의 항목이 있습니다. 나는 또 하나를 얻었으므로 2입니다. 또 하나는 3 개이고 다른 하나는 ... 2382입니다. 더 이상 항목이 없어서 2382가 있습니다. 다시 요청하지 않기 때문에 다시 묻지 마십시오.

수집 : 2382 개의 품목이 있습니다. 나는 이미 그것을 알고있다.

컬렉션은 일반적으로 모든 요소의 위치를 ​​이미 알고 있으며 요청시 찾아서 생성하거나 찾을 필요가 없습니다. 열거 형보다 더 구체적입니다.

내 의견으로는 Enumerable과 Collection의 차이점은 Collection과 List의 차이점보다 훨씬 큽니다. 사실 나는 Collection과 List의 실질적인 차이점을 생각하기 위해 고심하고 있지만 List는 더 나은 검색 및 주문 방법을 제공한다고 생각합니다.

컬렉션의 다른 유형을 포함 Queue하고 Stack,뿐만 아니라 Dictionary.

이러한 유형의 이름은 매우 유용합니다. 대기열과 스택을 실제 대응 물로 생각할 수 있으며 목록과의 차이점을 고려할 수 있습니다.


"컬렉션과리스트의 실질적인 차이를 생각하기 위해 고군분투하고 있습니다." ... 나중에 당신이 대답 할 것입니다. A는 List입니다 ICollection하지만은 ICollection항상 아닙니다 List( Queue, Stack, Dictionary, ...)
스티븐 Jeuris

@Steven 매우 답답한 답변입니다. 나는 이것이 중요한 차이점이라는 데 동의하지만 실제적인 차이점이라고는 생각하지 않습니다. 사용자에게 무엇을 의미합니까?
커크 브로드 허스트

쉽다! :) Queue<int> queue = (Queue<int>)list;InvalidCastException때가 list아닌 을 던질 것이다 Queue<int>. 대기열과 목록의 차이점은이 질문의 범위를 벗어납니다.
Steven Jeuris

IEnumerable의 중요한 측면은 현재 항목 과 다음 항목을 반환 할 수 있다는 것이 아닙니다. 본질적으로 IEnumerable 만 구현하는 것은 쿼리 할 때 멤버의 임의 항목을 반환 할 수 없으며 현재 항목과 다음 항목 만 반환합니다.
cori

@ cori 그것은 내 대답보다 훨씬 명확하게 표현하는 매우 간결한 방법입니다.
커크 브로드 허스트

-1

쿼리 가능 :

.ToList ()를 수행하여 항목을 실제로 반복 할 때까지 쿼리가 실행되지 않습니다.

IEnumerable :

전달 전용 항목 목록. 항목 0-3을 통과하지 않으면 "항목 4"에 도달 할 수 없습니다. 읽기 전용 목록에는 추가하거나 제거 할 수 없습니다. 여전히 지연된 실행을 사용할 수 있습니다.

IList :

메모리의 전체 목록에 대한 임의 액세스는 추가 및 제거를 지원합니다.

ICollection :

IEnumerable과 IList 사이에 있습니다. "최상의"는 요구 사항에 따라 다릅니다. 항목 만 표시하려는 경우 일반적으로 IEnumerable이 "충분히 양호"하지만 최소한 항상 일반 변형을 사용하십시오.


이 답변은 이전 답변에 이미 게시 된 것보다 가치있는 것을 추가하지 않는 것으로 보입니다
gnat

그것은 모두에 대한 간단한 개념입니다
Zia Qammar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.