2012-03-07 29 views
10

Recibo una Lista de tipo de marco en entidad y solo quiero devolver los valores distintos de la Lista. Estoy usando el siguiente enfoque, sin embargo, no es uniquifying la lista. ¿Alguna sugerencia?Crear una lista distinta de tipo personalizado en C#

Param: List<Flag> flags

List<Flag> distinctFlags = flags.Distinct().ToList(); 

Los valores de bandera son los siguientes: ID, Bandera, FlagValue. ¿Puedo usar linq en esta instancia?

Gracias.

+0

¿Cuáles son sus valores de entrada y lo qué se puede esperar como salida? –

+0

¿Esto está dentro o fuera de un contexto de db? Muestra más código por favor. Y si puedes, da un ejemplo de los datos antes y después de la transformación. –

+1

Agrupalos y elige un ganador. http://stackoverflow.com/questions/489258/linq-distinct-on-a-particular-property/491832#491832 –

Respuesta

14

Suponiendo Flag es uno de sus modelos de entidad, se puede utilizar un partialclass y anular Equals y GetHashCode. Esto también asume que tiene una propiedad Id en su Flagclass que tiene identidades únicas.

//this namespace MUST match the namespace of your entity model. 
namespace Your.Entity.Model.Namespace 
{ 
    public partial class Flag 
    { 
     public override bool Equals(object obj) 
     { 
      var item = obj as Flag; 

      if (item == null) 
      { 
       return false; 
      } 

      return this.Id.Equals(item.Id); 
     } 

     public override int GetHashCode() 
     { 
      return this.Id.GetHashCode(); 
     } 
    } 
} 

uso sería así

List<Flag> distinctFlags = allFlags.Distinct().ToList(); 
+1

También debe implementar 'IEquatable ' en el tipo. – svick

+0

Y probablemente anule '==' y '! =' –

+0

Solo necesita implementar 'Equals' y' GetHashCode'. Simplemente asegúrese de que su valor de código hash nunca cambie, el valor DEBE ser INMUTABLE. – Enigmativity

1

Probablemente flags es una lista de tipo de referencia, y distinta no funciona como se espera! Esto porque Distinct() no funciona en el valor del indicador en la lista, sino en sus referencias de memoria (que son todas diferentes).

Tienes que escribir una clase comparer que enseñe a Distinct cómo comparar la bandera igual. Suponga que tiene esta clase de la bandera:

public class flag 
{ 
    public string Name { get; set; } 
    public string Code { get; set; } 
} 

debe crear una clase comparador de esta manera:

class FlagComparer : IEqualityComparer<flag> 
{ 
    // Products are equal if their names and product numbers are equal. 
    public bool Equals(flag x, flag y) 
    { 

     //Check whether the compared objects reference the same data. 
     if (Object.ReferenceEquals(x, y)) return true; 

     //Check whether any of the compared objects is null. 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 

     //Check whether the products' properties are equal. 
     return x.Code == y.Code && x.Name == y.Name; 
    } 
} 

y llame a su declaración:

List distinctFlags = flags.Distinct(new FlagComparer()).ToList(); 

De esta manera, el método distinto sabe exactamente cómo comparar la istance de la bandera de igualdad.

ACTUALIZACIÓN

Basado en su comentario, si Wanto seguir mi sugerencia, debe escribir la base comparador de la siguiente manera:

class FlagComparer : IEqualityComparer<flag> 
    { 
     // Products are equal if their names and product numbers are equal. 
     public bool Equals(flag x, flag y) 
     { 

      //Check whether the compared objects reference the same data. 
      if (Object.ReferenceEquals(x, y)) return true; 

      //Check whether any of the compared objects is null. 
      if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
       return false; 

      //Check whether the products' properties are equal. 
      return x.HostID == y.HostID && x.RuleID == y.RuleID && x.Flag == y.Flag && x.FlagValue == y.FlagValue; 
     } 
    } 

Por supuesto, cada propiedad debe ser un tipo de valor .

Echa un vistazo aquí para aclarar a sí mismo:

+1

Esto funcionaría, pero reemplazando 'Equals()' e implementando 'IEquatable ' es el enfoque más común, porque significa que no tiene que especificar el comparador cada vez. – svick

Cuestiones relacionadas