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 , myColl 및 myEnum은 모두 동일한 객체를 가리 킵니다. 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

ICollection 및 IEnumerable에 대한 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.