Contains in Class List

Asked

Viewed 1,054 times

3

I have my class, which has 2 classes within 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 there is a specialty within that list

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

With contains there is also

Someone has an idea?

  • what are the attributes of Specificity?

  • I just edited the question Tuyoshi

5 answers

5


With regard to . Contains()

The method .Contains() of List<T> has a peculiarity that is to use the comparator returned by Equalitycomparer.default. According to the documentation:

The Default property checks if T implements the System.Iequatable interface and, if so, returns an Equalitycomparer that uses this implementation. Otherwise, it returns an Equalitycomparer that uses Object.Equals and Object.Gethashcode replacements provided by T.

That is, you can implement the interface IEqualityComparer<T> in its class or override the method base.Equals() and that will be the method of comparison used.

But why implement IEqualityComparer<T>?

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

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

Any Vs Contain

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

The .Contains() is an instance method and therefore complexity is dependent on the collection itself. In the case of a List<T> complexity is O(n), while in a HashSet complexity would be O(1).

Already the .Any() is an extension whose complexity is always O(n), since it will go through the entire collection, apply the delegate passed to each element and return when find an element whose delegate returns true.

Finally, the .Any() due to the delegate, is more flexible than the .Contains() which accepts only one object.

3

The Any works, however you are probably comparing different specialty objects, but they seem to be the same, by having 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 the guy 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. Ai in this case could do the way you were trying with the Any:

var hasAny = lista.Any(x => x.Especialidade == Esp);

1

You can search by name or Id in the example below I am looking for the name

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

1

In this case there is the need for you to implement a customization of this operator with specific rules for comparison between objects, if it does not exist it is compared the Hashcode of each object, an example of 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: http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80). aspx

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();
    }
  • It works but there is no search for the item. The only thing you are doing is to confirm that there is at least one nonzero specialty within listaProfEsp.

  • But from what I understand he wants to see if there is an entity inside why he wanted to use contains, if it is to check if a specific one existed then he would look for Id, name ... etc

  • Correct, he wanted to see if there is a specific specialty within the list, not if there is any. I agree that the question may seem that he wants to see only if there is something inside, but given that the OP says var lista.Any(x => x.Especialidade == Esp);, it was assumed that he wanted to look for something specific.

  • I just read again and you sure changed there...

  • The only thing I would add is to, instead of using idEspecialidade, access the property directly ID of lista1.

  • 1

    I agree altered there was even easier to exemplify...

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.