programing

목록 또는 I 목록

yellowcard 2023. 5. 20. 10:38
반응형

목록 또는 I 목록

C#에서 목록보다 I 목록을 사용하려는 이유를 설명할 수 있는 사람이 있습니까?

관련 질문:노출하는 것이 나쁜 것으로 간주되는 것입니까?

다른 사용자가 사용할 라이브러리를 통해 클래스를 노출하는 경우 일반적으로 구체적인 구현보다는 인터페이스를 통해 해당 클래스를 노출합니다.이것은 당신이 나중에 다른 구체적인 수업을 사용하기 위해 수업의 실행을 바꾸기로 결정한 경우에 도움이 될 것입니다.이 경우 라이브러리 사용자는 인터페이스가 변경되지 않으므로 코드를 업데이트할 필요가 없습니다.

만약 당신이 단지 내부적으로 그것을 사용하고 있다면, 당신은 그다지 신경 쓰지 않을 것이고, 그리고 사용할 것입니다.List<T>괜찮을지도 모릅니다.

덜 인기 있는 대답은 프로그래머들이 그들의 소프트웨어가 전 세계적으로 재사용되는 것처럼 가장하는 것을 좋아한다는 것입니다. 사실 대부분의 프로젝트는 소수의 사람들에 의해 유지될 것이고 인터페이스 관련 사운드비트가 아무리 훌륭해도, 당신은 자신을 속이는 것입니다.

건축 우주 비행사들..NET 프레임워크에 이미 포함된 항목에 추가하는 IList를 작성할 수 있는 기회는 너무 멀어서 "베스트 프랙티스"를 위한 이론적 젤리토트입니다.

소프트웨어 우주비행사

분명히 만약 여러분이 인터뷰에서 어떤 것을 사용하는지 질문을 받는다면, 여러분은 목록을 작성하고, 미소를 지으며, 둘 다 그렇게 영리한 것에 대해 기뻐하는 것처럼 보입니다.API를 사용하는 일반인의 경우 목록을 작성합니다.당신이 제 요점을 이해하기를 바랍니다.

인터페이스는 약속(또는 계약)입니다.

항상 약속이 그렇듯이 - 작을수록 좋습니다.

어떤 사람들은 "항상 사용"이라고 말합니다.IList<T>List<T>".
그들은 당신이 당신의 메소드 서명을 변경하기를 원합니다.void Foo(List<T> input)void Foo(IList<T> input).

이 사람들은 틀렸습니다.

그것보다 더 미묘한 것입니다.를 하는 경우IList<T>당신의 라이브러리에 대한 공개 인터페이스의 일부로서, 당신은 아마도 미래에 사용자 정의 목록을 만들 수 있는 흥미로운 옵션을 남깁니다.당신은 그 선택권이 필요하지 않을지도 모르지만, 그것은 논쟁입니다.그것은 구체적인 형식이 아닌 인터페이스를 반환해야 한다는 전체적인 주장이라고 생각합니다.언급할 가치가 있지만, 이 경우에는 심각한 결함이 있습니다.

사소한 반론으로, 당신은 모든 발신자가 필요하다는 것을 발견할 수 있습니다.List<T>어쨌든, 그리고 호출 코드는 흩어져 있습니다..ToList()

그러나 훨씬중요한 것은 IList를 매개 변수로 수락하는 경우 주의하는 것이 좋습니다.IList<T>그리고.List<T>같은 행동을 하지 마세요.이름의 유사성에도 불구하고, 그리고 인터페이스를 공유함에도 불구하고, 그들은 동일한 계약을 노출하지 않습니다.

다음 방법이 있다고 가정합니다.

public Foo(List<int> a)
{
    a.Add(someNumber);
}

도움이 되는 동료가 수용 방법을 "반발"합니다.IList<int>.

당신의 코드는 이제 깨졌습니다, 왜냐하면int[]IList<int>크기는 고정되어 있습니다.ICollection<T>)IList<T>할 때 합니다.IsReadOnly컬렉션에서 항목을 추가하거나 제거하기 전에 플래그를 지정합니다.List<T>하지 않다.

Liskov 대체 원칙(간체)은 파생된 형식이 추가 전제 조건이나 사후 조건 없이 기본 형식 대신 사용될 수 있어야 한다고 명시합니다.

이것은 마치 리스코프 대체 원칙을 깨는 것처럼 느껴집니다.

 int[] array = new[] {1, 2, 3};
 IList<int> ilist = array;

 ilist.Add(4); // throws System.NotSupportedException
 ilist.Insert(0, 0); // throws System.NotSupportedException
 ilist.Remove(3); // throws System.NotSupportedException
 ilist.RemoveAt(0); // throws System.NotSupportedException

하지만 그렇지 않습니다.이에 대한 대답은 예제에서 IList<T>/Icollection<을 사용했다는 것입니다.그릇된I 컬렉션을 사용하는 경우 <IsReadOnly 플래그를 확인해야 합니다.

if (!ilist.IsReadOnly)
{
   ilist.Add(4);
   ilist.Insert(0, 0); 
   ilist.Remove(3);
   ilist.RemoveAt(0);
}
else
{
   // what were you planning to do if you were given a read only list anyway?
}

누군가가 배열이나 목록을 건네주면 코드가 제대로 작동합니다. 매번 플래그를 확인하고 폴백이 있으면...하지만 정말로; 누가 그런 짓을 할까요?당신의 메소드에 추가 멤버를 포함할 수 있는 목록이 필요한지 미리 알지 못합니까? 메소드 서명에 명시되어 있지 않습니까? 같은 읽기 전용 목록을 무엇을 했습니까?int[]?

대체할 수 있습니다.List<T>를사하코로드를 IList<T>/ICollection<T> 정확하게다음을 대체할 수 있다고 보장할 수 없습니다.IList<T>/ICollection<T>를사하코로드를 List<T>.

구체적인 유형 대신 추상화를 사용하는 많은 주장에서 단일 책임 원칙/인터페이스 분리 원칙에 대한 호소가 있습니다. 가능한 한 좁은 인터페이스에 의존합니다.의 경우, 만약 여러분이 사중경우인용경대를 한다면,List<T>그리고 당신은 당신이 대신 더 좁은 인터페이스를 사용할 수 있다고 생각합니다 - 왜 그렇지 않습니다.IEnumerable<T>항목을 추가할 필요가 없는 경우 이 방법이 더 적합한 경우가 많습니다.해야 할 , 타입인 컬션에추가할야경콘사타용고하입을트크리우해렉,▁the,List<T>.

나를 위해.IList<T>)ICollection<T>NET .NET은 .NET과의 관계를 보여줍니다. IsReadOnly최소한의 놀라움의 원칙을 위반합니다.:Array항목 추가, 삽입 또는 제거를 절대 허용하지 않으므로 Add, Insert 및 Remove 메서드를 사용하는 인터페이스를 구현할 수 없습니다.(https://softwareengineering.stackexchange.com/questions/306105/implementing-an-interface-when-you-dont-need-one-of-the-properties) 참조)

아이즈IList<T>조직에 적합합니까? 메소드 서명을 IList<T>List<T>그들에게 어떻게 요소를 추가할 것인지 물어봅니다.IList<T>만약그모른면다에 ,IsReadOnly(대부분의 사람들은 그렇지 않습니다), 그러면 사용하지 않습니다.IList<T>전혀.


IsReadOnly 플래그는 ICollection에서 가져온 것입니다.항목을 컬렉션에 추가하거나 컬렉션에서 제거할 수 있는지 여부를 나타냅니다. 그러나 항목을 실제로 혼동하기 위해 항목을 바꿀 수 있는지 여부를 나타내는 것은 아니며, Arrays(IsReadOnlys == true 반환)의 경우에는 항목을 바꿀 수 있습니다.

IsReadOnly에 대한 자세한 내용은 ICollection의 smsdn 정의를 참조하십시오.<.IsRead Only

List<T>는 의구인구니다현의 특정 입니다.IList<T> 배열과 할 수 입니다.T[]정수 인덱스를 사용합니다.를 할 때IList<T>메소드의 인수 유형으로 컨테이너의 특정 기능이 필요하다는 것만 지정합니다.

예를 들어, 인터페이스 사양은 특정 데이터 구조를 사용하도록 강제하지 않습니다.의 .List<T>요소를 선형 배열로 액세스, 삭제 및 추가할 때 동일한 성능이 발생합니다. 지원하는 할 수 즉, 이 더 저렴하지만( 비용이 더 듭니다. ( .NET 그러링구상일있수다니습끝추것비는더더훨하액랜쌉니저시다는씬덤스이한세정간하지만렴가이에요경를우소의해신크상할나대목록에원된현을는되지▁(.▁instead▁however일▁(▁the▁listnet▁an▁imaginenoteation,▁linked,▁that▁you▁.비더▁to랜▁implement-액훨시▁could다니쌉씬는▁a▁forNET은 매우 비쌉니다.)LinkedList<T>구현하지 않음IList<T>.)

이 는 또한 수 .이 예에서는 특정 액세스 성능 특성이 필요할 때마다 사용합니다.에 대해 됩니다.List<T> "은 설서다이는현다구니음합을명▁"▁thelements다▁document▁imp구이니it현▁"합다를 구현합니다.IList<T>필요에 따라 크기가 동적으로 증가하는 어레이를 사용하는 일반 인터페이스입니다.")

또한 필요한 최소한의 기능을 노출하는 것도 고려해 볼 수 있습니다. 아마도 목록의 내용을 변경하는 것을 해야 할 입니다.IEnumerable<T> 그렇고요.IList<T>확장됩니다.

저는 왜 당신이 구체적인 구현보다 인터페이스를 사용해야 하는지를 정당화하는 대신, 왜 당신이 인터페이스보다 구체적인 구현을 사용해야 하는지를 정당화하려고 노력합니다.정당화할 수 없는 경우 인터페이스를 사용합니다.

IList<T>는 인터페이스이므로 다른 클래스를 상속하고 IList<를 구현할 수 있습니다.목록을 상속하는 동안 <사용자가 이 작업을 참조하십시오.

예를 들어 클래스 A가 있고 클래스 B가 상속받으면 목록을 사용할 수 없습니다.T>

class A : B, IList<T> { ... }
public void Foo(IList<Bar> list)
{
     // Do Something with the list here.
}

이 경우 IList<Bar> 인터페이스를 구현하는 모든 클래스를 통과할 수 있습니다.대신 List<Bar>를 사용한 경우 List<Bar> 인스턴스만 전달할 수 있습니다.

IList<Bar> 방식은 List<Bar> 방식보다 느슨하게 결합됩니다.

TDD와 OOP의 원칙은 일반적으로 구현이 아닌 인터페이스로 프로그래밍하는 것입니다.

사용자 지정 구성이 아닌 언어 구성에 대해 기본적으로 이야기하기 때문에 일반적으로 문제가 되지 않지만, 예를 들어 목록이 필요한 것을 지원하지 않는다는 것을 알게 되었다고 가정해 보겠습니다.만약 당신이 앱의 나머지 부분에서 IList를 사용했다면, 당신은 당신 자신의 사용자 정의 클래스로 List를 확장할 수 있고 여전히 리팩터링 없이 그것을 전달할 수 있습니다.

이렇게 하는 데 드는 비용은 최소한입니다. 나중에 두통을 줄이는 것은 어떨까요?이것이 바로 인터페이스 원리에 관한 것입니다.

구현보다 인터페이스를 사용하는 가장 중요한 경우는 API에 대한 매개 변수입니다.API가 List 매개변수를 사용하는 경우, 이 매개변수를 사용하는 사용자는 List를 사용해야 합니다.매개 변수 유형이 IList이면 호출자는 훨씬 더 자유롭고 코드를 작성할 때 존재하지도 않았던 클래스를 사용할 수 있습니다.

목록 대 I 목록 질문(또는 답변) 중 어느 것도 서명 차이를 언급하지 않는다고 가정합니다.(이것이 제가 SO에서 이 질문을 검색한 이유입니다.

따라서 적어도 .NET 4.5(2015년경) 이후에는 IList에서 찾을 수 없는 List에 포함된 방법이 있습니다.

  • 범위 추가
  • 읽기 전용
  • 이진 검색
  • 용량.
  • 모두 변환
  • 존재한다
  • 찾기
  • 모두 찾기
  • 색인 찾기
  • 마지막 찾기
  • 마지막 인덱스 찾기
  • 각각
  • 범위 가져오기
  • 범위 삽입
  • 마지막 인덱스:
  • 모두 제거
  • 범위 제거
  • 종류
  • 대상 배열
  • 트림 초과
  • 모두를 위한 참

5이 .NET 5.0 파일을 대체하면 ?System.Collections.Generic.List<T>System.Collection.Generics.LinearList<T>.NET은 항상 이름을 소유합니다.List<T>하지만 그들은 보장합니다.IList<T>는 계약입니다.따라서 IMHO 우리(적어도 나)는 누군가의 이름을 사용해서는 안 되며(이 경우에는 .NET이지만) 나중에 문제가 발생합니다.

를 사용하는 IList<T>하며, 을 자유롭게 할 수 .IList

모든 개념은 기본적으로 구체적인 구현보다 인터페이스를 사용하는 이유와 관련하여 위의 대부분의 답변에 명시되어 있습니다.

IList<T> defines those methods (not including extension methods)

IList<T> MSDN 링크

  1. 더하다
  2. 분명한
  3. 포함하다
  4. 복사 대상
  5. 열거자 가져오기
  6. 색인 Of
  7. 삽입
  8. 제거한다.
  9. 제거 위치

List<T>에서는 이러한 9가지 방법(확장 방법 제외)을 구현하며, 여기에 약 41개의 공개 방법이 있으며, 이는 응용 프로그램에서 어떤 방법을 사용할지 고려할 때 중요합니다.

List<T> MSDN 링크

IList 또는 ICollection을 정의하면 인터페이스의 다른 구현에 사용할 수 있기 때문입니다.

IList 또는 ICollection에서 주문 컬렉션을 정의하는 IOrderRespository를 사용할 수 있습니다.그런 다음 IList 또는 I 컬렉션에서 정의한 "규칙"을 준수하는 주문 목록을 제공하기 위해 다양한 종류의 구현을 사용할 수 있습니다.

다른 포스터의 조언에 따르면 IList<>는 거의 항상 선호되지만 WCF DataContractSerializer를 사용하여 두 번 이상의 직렬화/직렬화 사이클을 통해 IList<>를 실행할 때 .NET 3.5sp1에 버그가 있습니다.

이제 이 버그를 해결하기 위한 SP가 있습니다. KB 971030

인터페이스는 최소한 당신이 기대하는 메소드를 얻을있도록 보장합니다. 즉, 인터페이스의 정의를 알고 있기 때문입니다. 즉, 인터페이스를 상속하는 모든 클래스에서 구현해야 하는 모든 추상 메소드입니다.따라서 어떤 사람이 인터페이스에서 일부 추가 기능을 위해 상속받은 것 외에 여러 가지 방법으로 자신만의 거대한 클래스를 만들지만 사용자에게 아무런 쓸모가 없는 경우 하위 클래스(이 경우 인터페이스)에 대한 참조를 사용하고 구체적인 클래스 개체를 할당하는 것이 좋습니다.

추가적인 장점은 당신이 콘크리트 클래스의 메소드 중 몇 가지만 구독하고 있기 때문에 당신의 코드가 콘크리트 클래스의 변경으로부터 안전하다는 것입니다. 그리고 콘크리트 클래스가 당신이 사용하고 있는 인터페이스로부터 상속받는 한, 그것들은 당신이 거기에 있을 것입니다.따라서 구체적인 구현을 작성하는 코더는 자신의 구체적인 클래스를 변경하거나 더 많은 기능을 추가할 수 있습니다.

이 주장은 구현이 아닌 인터페이스에 대해 프로그래밍하는 순수한 OO 접근 방식을 포함하여 여러 각도에서 살펴볼 수 있습니다.이렇게 하면 IList를 사용하는 것은 처음부터 정의한 인터페이스를 사용하고 전달하는 것과 동일한 원리를 따릅니다.저는 또한 일반적으로 인터페이스가 제공하는 확장성과 유연성 요소를 믿습니다.IList<T>를 구현하는 클래스를 확장하거나 변경해야 하는 경우, 사용 코드는 변경할 필요가 없습니다. IList Interface 계약이 준수하는 내용을 알고 있습니다.그러나 구체적인 구현 및 목록 사용 <클래스가 변경되면 호출 코드도 변경해야 할 수 있습니다.IList<T>를 준수하는 클래스는 List<를 사용하여 구체적인 유형에 의해 보장되지 않는 특정 동작을 보장하기 때문입니다..

또한 목록의 기본 구현을 수정하는 것과 같은 작업을 수행할 수 있는 권한을 가집니다.클래스에서 IList<T>를 구현합니다.Add, .Remove 또는 다른 IList 메서드는 개발자에게 많은 유연성과 성능을 제공합니다. 그렇지 않으면 List<에 의해 미리 정의됩니다.T>

일반적으로 좋은 접근 방식은 API를 사용하는 공개 API에서 IList를 사용한 다음(적절한 경우 및 의미를 나열해야 함) 내부적으로 List를 사용하여 API를 구현하는 것입니다.이렇게 하면 클래스를 사용하는 코드를 끊지 않고 IList의 다른 구현으로 변경할 수 있습니다.

클래스 이름 List는 다음 .net 프레임워크에서 변경될 수 있지만 인터페이스가 계약이므로 인터페이스는 변경되지 않습니다.

API가 각 루프 등에 대해서만 사용될 경우 대신 IEnumberable을 노출하는 것을 고려할 수 있습니다.

언급URL : https://stackoverflow.com/questions/400135/listt-or-ilistt

반응형