Contains in Class List

3

I have my class, which has 2 classes inside it.

public class ProfEsp {
public Especilidade Especialidade {get;set;}
public Profissional Profissional {get;set;}

}
public class Especialidade {
public int Id {get;set;}
public string Nome {get;set;}
}

public class Profissional {
public int Id {get;set;}
public string Nome {get;set;}
}

So I have my list

var lista = new List<ProfEsp>();

I want to check if a specialty exists within this list

I tried using var lista.Any(x => x.Especialidade == Esp);

With contains does not have as well

Does anyone have an idea?

    
asked by anonymous 22.05.2014 / 19:46

5 answers

5

Regarding .Contains ()

The .Contains() method of List<T> has a peculiarity which is to use the comparer returned by EqualityComparer.Default. According to the documentation:

  

The Default property checks whether T implements the System.IEquatable interface and, if so, returns an EqualityComparer that uses this implementation. Otherwise, it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T.

In other words, you can implement the IEqualityComparer<T> interface in your class or override the base.Equals() method and this will be the comparison method used.

But why implement IEqualityComparer<T> ?

When you use .Equals() of the interface, there is a guarantee that the types of the original object and the object to compare are the same. Not only does it make programming safer, it has a slight impact on performance, since, unlike base.Equals() , boxing / unboxing does not occur in the comparison.

This scenario becomes more important when there is extensive use of comparisons where the costs of boxing / unboxing are no longer negligible.

Any Vs Contain

An interesting analysis is the comparison of complexities between .Any() and .Contains() .

.Contains() is a method of the instance and therefore the complexity is dependent on the collection itself. In the case of a% with% complexity is O (n), while in% with% complexity would be O (1).

Since List<T> is an extension whose complexity is always O (n), since it will scroll through the entire collection, apply the delegate passed to each element, and return when it finds an element whose delegate returns HashSet . p>

Finally, the% w / o% due to the delegate is more flexible than the% w / w that only accepts an object.

    
22.05.2014 / 20:30
3

Any works, though you're probably comparing different specialty objects, but they seem to be the same, because they have the same values in the properties.

Try to compare a property that identifies Especialidade :

var lista.Any(x => x.Especialidade.Id == Esp.Id)

Or implement the == operator for type Especialidade :

public static bool operator ==(Especialidade x, Especialidade y) 
{
    return x.Id == y.Id;
}

And also the method Equals ... to maintain consistency with the above operator. Here in this case could do the way you were trying with Any :

var hasAny = lista.Any(x => x.Especialidade == Esp);
    
22.05.2014 / 19:52
1

You can search for the name or Id in the example below I'm looking for the name

var ProfEsp = lista.SingleOrDefault(x => x.Especialidade.Nome == "Programador" );
if(ProfEsp!=null){
  // achou especialidade!
}
    
22.05.2014 / 19:53
1

In this case there is a need to implement a customization of this operator with specific rules for object comparison, if there is no HashCode of each object is compared, an example comparison:

public class Especilidade 
{
    public string Nome  { get; set; }
    public string Categoria { get; set; }

    public static bool operator ==(Especilidade a, Especilidade b)
    {
        // mesma instancia, retorna true.
        if (System.Object.ReferenceEquals(a, b))
        {
            return true;
        }

        // Caso um deles sejam nulos, retorna false
        if (((object)a == null) || ((object)b == null))
        {
            return false;
        }

        // Retorna true se o campos forem iguais
        return a.Nome == b.Nome && a.Categoria == b.Categoria;
    }

    public static bool operator !=(Especilidade a, Especilidade b)
    {
        return !(a == b);
    }
}

See this documentation, it will help you with comparisons between objects: link

    
22.05.2014 / 19:59
1

I tested it and it worked like this:

var listaProfEsp = new List<ProfEsp>();

     var lista1 = new ProfEsp();
     lista1.Especialidade = new Especialidade
     {
         Id = 1,
         Nome = "teste"
     };

    listaProfEsp.Add(lista1);            
    var exist = listaProfEsp.Any(x => x.Especialidade.Id == lista1.Especialidade.Id);

    if (exist)
    {
       Console.Write("exist");
       Console.ReadLine();
    }
    else
    {
       Console.Write("não exist");
       Console.ReadLine();
    }
    
23.05.2014 / 14:08