2012-02-01 10 views
6

Soy muy nuevo a los genéricos y yo estoy tratando de escribir una clase simple que será genérica, sino también permitir la clasificación de algún tipo en una variable miembro de cuerdas.genéricos e implementar IComparable

En el momento en que tienen una clase básica, pero cuando trato de poner en práctica el miembro de interfaz CompareTo() Me aparece un error en la parte superior me dice que no está implementada. Cuál es el problema aquí?

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); 
     } 
    } 
} 

Respuesta

7

Hay dos interfaces IComparable y IComparable<U>. IComparable es el más antiguo (que vino antes de los genéricos) que requiere que las instancias se comparen con objetos arbitrarios. IComparable<U> requiere que las instancias se comparen con las instancias de U. Si desea declarar que va a comparar los casos de SortableGenericType en campos nombreDeCadena esto es lo que debe hacer:

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

Si también desea implementar 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>); 
     } 
    } 

Si la clase era una colección que va a contener elementos de tipo T y que necesitan esos artículos a ser ordenable (esto no es lo que pide, pero es el escenario más común) de lo que se necesita para ser TIComparable<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

No haría 'if (obj.GetType()! = GetType()) return -1;', porque entonces su comparación ya no es antisimétrica o reflexiva. – porges

+0

Es cierto. Pero no sé qué se supone que debo hacer en ese caso. ¿Cuál sería tu sugerencia? –

+0

En su segunda función CompareTo utiliza esta línea: CompareTo volver (obj como SortableGenericType ); ¿Compara esta línea implícitamente el objeto actual que tenemos con el que pasó sin hacer referencia al elemento actual en la línea? – CSharpened

5

IComparable define el método public int CompareTo(object obj). Tenga en cuenta el tipo de parámetro: es object, no es de su propio tipo. Es por eso que en realidad no está implementando la interfaz.

Lo que hay que hacer es poner en práctica IComparable<SortableGenericType<T>>

+0

Perfecto. Muchas gracias. Supuse que como mi tipo era un objeto en sí mismo, estaría bien hacerlo. Gracias por la explicación. – CSharpened

+1

Su tipo es un objeto, pero es un objeto específico. IComparable le permite comparar su objeto con CUALQUIER objeto, no solo con su tipo específico. –

Cuestiones relacionadas