다음과 같은 질문에 대한 답변 : List <T> 또는 IList <T>는 항상 인터페이스를 반환하는 것이 컬렉션의 구체적인 구현을 반환하는 것보다 낫다는 데 동의하는 것 같습니다. 그러나 나는 이것으로 어려움을 겪고 있습니다. 인터페이스를 인스턴스화하는 것은 불가능하므로 메서드가 인터페이스를 반환하는 경우 실제로는 여전히 특정 구현을 반환합니다. 두 가지 작은 방법을 작성하여 이것을 약간 실험했습니다.
public static IList<int> ExposeArrayIList()
{
return new[] { 1, 2, 3 };
}
public static IList<int> ExposeListIList()
{
return new List<int> { 1, 2, 3 };
}
그리고 내 테스트 프로그램에서 사용하십시오.
static void Main(string[] args)
{
IList<int> arrayIList = ExposeArrayIList();
IList<int> listIList = ExposeListIList();
//Will give a runtime error
arrayIList.Add(10);
//Runs perfectly
listIList.Add(10);
}
두 경우 모두 새 값을 추가하려고 할 때 컴파일러에서 오류가 발생하지 않지만 배열을로 노출하는 메서드는 내가 IList<T>
뭔가를 추가하려고 할 때 런타임 오류를 발생시킵니다. 그래서 내 방법에서 무슨 일이 일어나고 있는지 모르고 여기에 값 을 추가해야하는 사람들은 오류 위험없이 값을 추가 할 수 있도록 먼저 my IList
를 a List
에 복사해야 합니다. 물론 그들은과 그들이 경우있는 거 거래 볼 수있는 유형 체킹을 수행 할 수 있습니다 List
또는를 Array
하지만 그렇게하지 않으면, 그들은 컬렉션에 항목을 추가 할 그들이 다른 선택의 여지가 복사되지해야 IList
A를 List
하더라도, 이미List
. 배열은 절대로 노출되지 않아야 IList
합니까?
나의 또 다른 관심사는 연결된 질문 (강조 내) 에 대한 수용된 답변에 기반합니다 .
다른 사람들이 사용할 라이브러리를 통해 클래스를 노출하는 경우 일반적으로 구체적인 구현이 아닌 인터페이스를 통해 클래스 를 노출하려고합니다. 나중에 다른 구체적인 클래스를 사용하기 위해 클래스 구현을 변경하기로 결정한 경우 도움이됩니다. 이 경우 인터페이스가 변경되지 않으므로 라이브러리 사용자는 코드를 업데이트 할 필요가 없습니다.
내부적으로 만 사용하는 경우별로 신경 쓰지 않을 수 있으며 List를 사용해도 괜찮을 수 있습니다.
누군가가 실제로 값을 추가 / 제거하기 위해 IList<T>
내 ExposeListIlist()
방법 에서 얻은 내 방법을 사용했다고 상상해보십시오 . 모든 것이 잘 작동합니다. 그러나 이제 대답에서 알 수 있듯이 인터페이스를 반환하는 것이 더 유연하기 때문에 List 대신 배열을 반환합니다 (내쪽에는 문제가 없습니다!).
TLDR :
1) 인터페이스를 노출하면 불필요한 캐스트가 발생합니까? 상관 없어?
2) 때때로 라이브러리 사용자가 캐스트를 사용하지 않으면 메서드가 완벽하게 유지 되더라도 메서드를 변경할 때 코드가 손상 될 수 있습니다.
나는 아마도 이것을 지나치게 생각하고 있지만, 구현을 반환하는 것보다 인터페이스를 반환하는 것이 선호된다는 일반적인 합의를 얻지 못했습니다.
IEnumerable<T>
컴파일 시간이 안전합니다. 일반적으로 성능을 특정 형식으로 캐스팅하여 성능을 최적화하려는 모든 LINQ 확장 메서드를 계속 사용할 수 있습니다 ( 열거하는 대신 속성ICollection<T>
을 사용하는 것과 유사 함Count
).