IComparable 인터페이스가 오래되었거나“유해”합니까?


11

IComparable 한 방향으로 만 작동

Employee수업 이 있다고 가정 해 봅시다 . Employees한보기에서 이름별로 정렬하고 다른 주소별로 정렬 하여 표시하려고 합니다. 어떻게 달성 할 수 있습니까? 하지와 IComparable적어도되지 않은 관용적 인 방법.

IComparable 논리가 잘못된 곳에있다

인터페이스는를 호출하여 사용됩니다 .Sort(). Customer이름별로 정렬 된 보기에는 정렬 방법을 암시하는 코드가 전혀 없습니다.
반면에 Customer클래스는 사용 방법을 가정하고 있습니다.이 경우 이름별로 정렬 된 목록에서 사용됩니다.

IComparable 암시 적으로 사용됩니다

대안과 비교할 때 비교 논리가 어디에 사용되는지 또는 전혀 사용하지 않는 것은 매우 어렵습니다. 표준 IDE를 가정하고 Customer클래스 에서 시작한다고 가정하면

  1. 에 대한 모든 참조 검색 Customer
  2. 목록에 사용 된 참조를 찾으십시오.
  3. 그 목록이 .Sort()그들에게 전화 한 적이 있는지 확인하십시오

더 나쁜 IComparable것은 여전히 ​​사용중인 구현을 제거하면 오류나 경고가 표시되지 않습니다. 당신이 얻을 수있는 유일한 것은 당신이 생각하기에 너무 모호한 모든 장소에서 잘못된 행동입니다.

이러한 문제와 요구 사항 변경

내가 이것에 대해 생각하게 된 이유는 그것이 나에게 잘못 되었기 때문입니다. 나는 IComparable2 년 동안 내 응용 프로그램에서 행복하게 사용 하고 있습니다. 이제 요구 사항이 변경되었으며 사물을 두 가지 방식으로 정렬해야합니다. 이전 섹션에서 설명한 단계를 수행하는 것은 재미없는 일입니다.

질문

이 문제 는 대안으로 더 잘 제공되지 않는 유효한 유스 케이스를 보지 못하기 때문에 또는 IComparable보다 열등하다고 생각 합니다. 항상 사용 하거나 LINQ 를 사용하는 것이 좋습니까 , 아니면 여기에 표시되지 않는 장점 / 사용 사례가 있습니까?IComparer.OrderBy()
IComparer


2
새로운 "두 가지 다른 방법으로 정렬"요구 사항은 붉은 청어입니다. 이를 해결하려면 정렬 기능에 다른 비교기를 전달하기 만하면됩니다.
Robert Harvey

@RobertHarvey 그렇다면 IComparable더 이상 사용 하지 않을 것이므로 내 요점이 강화됩니다.
R. Schmitz

당신이 사용하는 경우 잊지 마세요 SortedXXX컬렉션을, 그들 중 하나로 저장된 요소를 필요로 IComparable하거나이 가지고 IComparer제공. 또한 하나의 비교기로 자연 정렬 순서를 바꾸고 모든 IComparable객체에서 작동하도록하는 것은 사소한 일입니다 .
Berin Loritsch

2
두 개의 다른 인터페이스가 있는지는 중요하지 않습니다. 기본 비교 메커니즘 으로IComparable 간주됩니다 . 기본 비교 메커니즘을 재정의하려는 경우에 사용됩니다. IComparer
Robert Harvey

답변:


14

IComparable당신이 언급 한 제한이 있습니다, 맞습니다. .NET Framework 1.0에서 이미 사용 가능한 인터페이스로, 기능적 대안과 Linq를 사용할 수 없었습니다. 예, 이전 버전과의 호환성을 위해 주로 유지되는 오래된 프레임 워크 요소로 볼 수 있습니다.

그러나 많은 간단한 데이터 구조의 경우 한 가지 정렬 방법으로 충분하거나 자연 스럽습니다. 이러한 경우, 주문 관계를 구현하기 위해 하나의 표준 위치를 갖는 것이 OrderBy모든 장소에 대한 모든 호출에서 항상 동일한 논리를 반복하는 대신 코드 DRY를 유지하는 좋은 방법 입니다.

당신이 쓴 것처럼 당신은 "지금 2 년 동안 당신의 응용 프로그램에서 IComparable을 행복하게 사용하고 있습니다", 그래서 그것은 오랫동안 당신에게 잘 봉사 한 것으로 보입니다. 에 대한 모든 호출의 유효성을 검사, 변경 및 테스트 Sort해야 할 경우 여러 위치에서 동일한 종류의 정렬 논리를 수행하고 있다는 신호일 수도 있습니다 IComparable. 따라서이 논리를 더 많이 중앙 집중화하여 코드를 건조하게 만들 수 있습니다.


간단한 데이터 구조에 대한 좋은 지적. 그러나 마지막 단락은 100 % 의미가 없습니다. 를 사용하지 않으면 IComparable기존의 모든 정렬 코드가 해당 뷰에서 그대로 유지되지만 새보기에 대해 새로운 정렬 코드 만 추가합니다.
R. Schmitz

@ R.Schmitz IComparable당신이 작성한 구현 없이 기존의 정렬이 제대로 작동 했을까?
Robert Harvey

3
@ R.Schmitz : 물론, 지금은 항상 비교기를 제공 하기 위해 노력하고 있습니다 (물론 OrderBy를 사용하지 않는 한). 을 사용하면 IComparable기본 구현이 무료이며 때로는 해당 구현을 작성할 필요가 없습니다.
Robert Harvey

2
@ R.Schmitz : 마지막 의견은 요점을 잘 요약합니다. 그래도 조금 더 멀리 갈 것입니다. 와 같은 숫자 유형이 있다고 가정하십시오 BigInteger. 비교 연산자 / 인터페이스를 구현하지 않았다면 어떻게 IComparer를 직접 구현 하겠습니까? 효율적이거나 전혀 내부 데이터 구조에 액세스해야합니다. 고객과 같은 유형이 있다고 가정하십시오. 공공 속성은이에 정렬하고자 comparers 있습니다. 구현 : 나를 위해 그 차이의 IComparable<T>가 될 경우 무리 비교 자를 구현하기 위해 호출을 기대.
Eric Lippert

1
If I hadn't used IComparable, all the pre-existing sorting code would have been left untouched in their respective views, while I'd only add new sorting code for the new view.해서 IComparable이었다 더 나은 솔루션을 , 그것이 의미하지 않는 최적의 솔루션을 오늘 . 여기서 첫 번째 의견은 "IComparable 또는 아무것도 아니다"는 것을 의미하며, 사실은 아니지만 여러 가지 방법으로 문제를 해결할 수있었습니다. 응용 프로그램의 크기 / 규모가 커질 수 있으며, 적합 해 보였던 것들이 응용 프로그램의 증가하는 요구를 따라 가지 못할 수 있습니다.
Flater

1

나는 당신의 감정에 동의합니다 IComparable

그냥 비고를 봐 Array.Sort()

  • 배열의 각 요소는 배열의 IComparable다른 모든 요소와 비교할 수 있도록 인터페이스를 구현해야합니다 . (또는 예외가 발생 함)
  • 정렬이 성공적으로 완료되지 않으면 결과가 정의되지 않습니다.

그러나 우리는 이제 결코 동기 부여가되지 않을 것입니다! object.Equals()객체가 서로 같은지 확인하기 위해 객체를 서로 비교할 수있는 모든 객체에 대한 방법을 고려 하십시오.

이미 거기에 있지만 추가 작업이 완료되면 추가 Array.Sort()할 수 있습니다.object.Compare(object)

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