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 또는 다른 구체적인 클래스를 상속해야 함을 알고 있습니다 목록에서.