2012-02-01 3 views
6

Я очень новичок в дженериках, и я пытаюсь написать простой класс, который будет общим, но также позволяет сортировать некоторое описание в переменной-члене строки.Generics and Implementing IComparable

На данный момент у меня есть базовый класс, но когда я пытаюсь реализовать элемент интерфейса CompareTo(), я получаю сообщение об ошибке, говорящее, что он не реализован. В чем проблема?

using System; 

namespace GenericsPracticeConsole.Types 
{ 
    class SortableGenericType<T> : IComparable 
    { 
     private T t; 
     private string stringName; 

     public T name 
     { 
      get { return t; } 
      set { t = value; } 
     } 

     public int CompareTo(SortableGenericType<T> ourObject) 
     { 
      return stringName.CompareTo(ourObject.stringName); 
     } 
    } 
} 

ответ

7

Есть два интерфейса IComparable и IComparable<U>. IComparable - это более старый (который появился перед дженериками), который требует сравнения экземпляров с произвольными объектами. IComparable<U> требует, чтобы экземпляры сравнивались с экземплярами U. Если вы хотите, чтобы объявить, что вы будете сравнивать экземпляры SortableGenericType на stringName полях это то, что вы должны сделать:

class SortableGenericType<T> : IComparable<SortableGenericType<T>> 
{ 
    // 
} 

Если вы хотите реализовать IComparable:

class SortableGenericType<T> : IComparable, IComparable<SortableGenericType<T>> 
    { 
     private string stringName; 
     public T name { get; set; } 

     public int CompareTo(SortableGenericType<T> ourObject) 
     { 
     //I forgot to add this statement: 
     if(ourObject == null) 
      return -1; 
     return stringName.CompareTo(ourObject.stringName); 
     } 

     public int CompareTo(object obj) 
     { 
     if (obj.GetType() != GetType()) 
      return -1; 
     return CompareTo(obj as SortableGenericType<T>); 
     } 
    } 

Если ваш класс был сбор который будет содержать предметы типа T, и вам нужны были эти предметы для заказа (это не то, что вы просите, но это наиболее распространенный сценарий), чем вам потребуется T будет IComparable<T>:

class SomeCollection<T> where T : IComparable<T> 
    { 
     private List<T> items; 

     private void Sort() 
     { 
     // 
     T item1; 
     T item2; 
     if(item1.CompareTo(item2) < 0) 
     { 
      //bla bla 
     } 
     } 
    } 
+0

Я бы не сделал 'if (obj.GetType()! = GetType()) return -1;', потому что тогда ваше сравнение уже не является антисимметричным или рефлексивным. – porges

+0

Правда. Но я не знаю, что я должен делать в этом случае. Что бы вы сказали? –

+0

В вашей второй функции CompareTo вы используете эту строку: return CompareTo (obj as SortableGenericType ); Эта строка неявно сопоставляет текущий объект, который у нас есть, с переданным без фактического ссылки на текущий элемент в строке? – CSharpened

5

IComparable определяет метод public int CompareTo(object obj). Обратите внимание на тип параметра - это object, а не ваш собственный тип. Вот почему вы на самом деле не реализуете интерфейс.

Что вам нужно сделать, это реализовать IComparable<SortableGenericType<T>>

+0

Perfect. Огромное спасибо. Я предположил, что, поскольку мой тип сам по себе является объектом, что было бы хорошо сделать это. Спасибо за объяснение. – CSharpened

+1

Ваш тип - это объект, но это особый объект. IComparable позволяет сравнивать ваш объект с любым объектом, а не только с вашим конкретным типом. –