2009-02-02 4 views
7

좋아요, 아래 코드와 비슷한 시나리오가 있습니다. IComparable과 자식 클래스를 구현하는 부모 클래스가 있습니다.IComparable 및 컬렉션 정렬 방법에 문제가 있습니다.

class Parent : IComparable<Parent> 
class Child : Parent 

Child a = new Child(); 
Child b = new Child(); 
a.CompareTo(b); 

이제 위의 작품 좋은, 나는 아이의 두 개의 서로 위 InvalidOperationException이와 비록 실패 문제

List<Child> l = new List<Child>(); 
l.Add(b); 
l.Add(a); 
l.Sort(); 

개체를하지 비교할 수 있습니다. 누군가가 왜 이런 종류의 자식 클래스가 IComparable 인터페이스를 구현할 때 작동하지 않습니다 설명 할 수 또는 적어도 나를 않습니다. 여기에 좋아

public int CompareTo(IDType other) 
{ 
     return this.Name.ToString().CompareTo(other.ToString()); 
} 
+0

귀하의 샘플을 만들고있는 목록의 실제 제네릭 형식은 무엇입니까 ... 내가 추측하고있어 "새 목록 는()"오타 말한다? –

+0

아, 미안 해요 오타예요. List l = 새 목록 (); 제네릭 형식 목록을 만드는 것이 꽤 분명하다고 생각합니다. – CalvinR

+0

IComparable 구현의 코드를 볼 수 있습니까? –

답변

6

귀하의 유형 IComparable<Parent>보다는 IComparable<Child> 구현 내 실제 부모 클래스 내 compareTo와 구현입니다. MSDN docs for Sort에서 "기본 비교기 Comparer (T) .Default가 IComparable (T) 일반 인터페이스 또는 T 유형의 IComparable 인터페이스 구현을 찾을 수없는 경우 InvalidOperationException이 throw됩니다." 그리고 실제로 그것은 T가 Child 일 수 없습니다. List<Parent>으로 만들면 잘 될 것입니다.

편집 : 대안으로 (그리고 바람직하게는 IMO) IComparable<Child>을 구현하십시오. 현재 아동이 다른 아동과 현명하게 비교 될 수 있다는 것은 분명하지 않습니다. IComparable<Child> 구현 - 해당 구현이 기본 구현을 막을지라도 비교 가능성을 알립니다.

+0

내 비교가 잘 작동하지 않습니다. 단순히 부모 클래스에 저장된 문자열 멤버 변수의 비교 함수를 사용하고 있습니다. – CalvinR

+0

변경된 대답을 완전히 바꿨습니다. 뭔가 다른 것을 확인했습니다. :) –

+1

절대 쓰레기 인 사람은 부모 클래스에 비 제너릭 IComparable을 구현하면 잘 작동합니다. – CalvinR

3

나는 이것을 시도하고 동일한 오류가 발생했습니다. 내 생각 엔 List<Child>을 가지고 있기 때문에 IComparable<Parent>이 아닌 IComparable<Child>을 구현하는 사람을 찾고 있습니다.

컬렉션을 List<Parent>으로 변경하면 문제가있는 것 같습니다. 또는 하위가 IComparable<Child>을 구현하도록합니다 (부모의 구현에 위임 할 수 있음).

+0

그래, 불행히도 나는 곧 그런 식으로 일할 수 있도록 내 컬렉션을 바꾸지 않을 것이다. 그래서 나는 비 제네릭 IComparable을 구현하거나 그냥 정렬하고자하는 각각의 클래스에 일반적인 것을 구현해야 할 것이라고 생각한다. . – CalvinR

3

내 추측은 공분산/반항성과 관련이 있다고 생각합니다. 내가 아닌 일반적인에서 IComparable을 구현하기 위해 부모를 변경하고 이런 짓을 할 때

public class Parent : IComparable<Parent> 
    { 
     public int Age { get; set; } 


     public int CompareTo(Parent other) 
     { 

      return this.Age.CompareTo(other.Age); 
     } 

    } 

    public class Child : Parent 
    { 
     public string Name { get; set; } 
    } 

그러나, 그것은 일 : I 테스트

public class Parent : IComparable 
    { 
    public int Age { get; set; } 


    public int CompareTo(object other) 
    { 
     Parent p = other as Parent; 
     return this.Age.CompareTo(p.Age); 
    } 

} 

    public class Child : Parent 
    { 
     public string Name { get; set; } 
    } 

코드를 당신이 말했듯이 실패하기 때문에 나는 그 말을 그 이유는 와 그것을 :

List<Child> c = new List<Child>(); 
    c.Add(new Child { Age = 10, Name = "Alex" }); 
    c.Add(new Child { Age = 6, Name = "Jack" }); 
    c.Add(new Child { Age = 15, Name = "Bob" }); 

    c.Sort(); 
+0

그래, 나는 똑같은 것을 발견했다, 나는 아직도 Icomparable의 일반적인 형태를 사용할 수 있기를 바랐다. – CalvinR

관련 문제