Find item in a List with Contains method

2

I have an object of type Data, which has the attributes name (string) and transacaBloqueio (int). I have a Data List called SharedBlock data. I want to check if this list has an item already with the same name and same transaction as the last one as a parameter. If it does not have add, if it does not add. I am trying to use the contains method, but it is not working. It adds the same item already having an equal. What could be happening?

Data Class

public class Dado
    {
        private string nome;
        private int transacaoBloqueio;

        public string getNome()
        {
            return this.nome;
        }

        public int getTransacaoBloqueio()
        {
            return this.transacaoBloqueio;
        }

        public void setNome(string nomeDado)
        {
            this.nome = nomeDado;
        }

        public void setTransacaoBloqueio(int transacao)
        {
            this.transacaoBloqueio = transacao;
        }
    }


private List<Dado> dadosBloqueioCompartilhado= new List<Dado>();
private Dado dadoAtual = new Dado();
dadoAtual.setNome('A');
dadoAtual.setTransacaoBloqueio(1);

if (!dadosBloqueioCompartilhado.Contains(dadoAtual))
{
    dadosBloqueioCompartilhado.Add(dadoAtual);
}
    
asked by anonymous 27.05.2016 / 17:54

1 answer

5

When you create a classe and a lista dessa classe and try to verify that a value coexists within that list, there may be confusion in the Contains that checks the instance of the class and not the property itself.

Example:

Class Given

public class Dado
{
   public string Nome { get; set; }
   public int TransacaoBloqueio { get; set; }
}

Code 1:

IList<Dado> dadosBloqueioCompartilhado = new List<Dado>();

Dado dadoAtual = new Dado();
dadoAtual.Nome = "A";
dadoAtual.TransacaoBloqueio = 1;

if (!dadosBloqueioCompartilhado.Contains(dadoAtual))
{
    dadosBloqueioCompartilhado.Add(dadoAtual);
}

if (!dadosBloqueioCompartilhado.Contains(dadoAtual))
{
    dadosBloqueioCompartilhado.Add(dadoAtual);
}

In this code snippet, the first if will let you add the item to the list, and the second does not, because the classe instance already exists within that list is the

Code 2:

IList<Dado> dadosBloqueioCompartilhado = new List<Dado>();

Dado dadoAtual = new Dado();
dadoAtual.Nome = "A";
dadoAtual.TransacaoBloqueio = 1;

if (!dadosBloqueioCompartilhado.Contains(dadoAtual))
{
    dadosBloqueioCompartilhado.Add(dadoAtual);
}

dadoAtual = new Dado();
dadoAtual.Nome = "A";
dadoAtual.TransacaoBloqueio = 1;

if (!dadosBloqueioCompartilhado.Contains(dadoAtual))
{
    dadosBloqueioCompartilhado.Add(dadoAtual);
}

In this specific case you will get an unwanted surprise, because the list will have added the two items because, their instances are different and the Contains checks the instances instead of the values.

Code 3

Apparent solution to check the data that is contained in the class:

Create a class by implementing the IEqualityComparer interface:

public class ComparerDados : IEqualityComparer<Dado>
{
    public bool Equals(Dado x, Dado y)
    {
        return (x.Nome.Equals(y.Nome)) &&
            (x.TransacaoBloqueio.Equals(y.TransacaoBloqueio));
    }

    public int GetHashCode(Dado obj)
    {
        return 0;
    }
}

And with the code below it will check the data contained in the instance of the class with the Contains , verifying there the values contained in the instance of the class:

IList<Dado> dadosBloqueioCompartilhado = new List<Dado>();

Dado dadoAtual = new Dado();
dadoAtual.Nome = "A";
dadoAtual.TransacaoBloqueio = 1;

if (!dadosBloqueioCompartilhado.Contains(dadoAtual, new ComparerDados()))
{
    dadosBloqueioCompartilhado.Add(dadoAtual);
}

dadoAtual = new Dado();
dadoAtual.Nome = "A";
dadoAtual.TransacaoBloqueio = 1;

if (!dadosBloqueioCompartilhado.Contains(dadoAtual, new ComparerDados()))
{
    dadosBloqueioCompartilhado.Add(dadoAtual);
}

In this case you will only have one item in the list.

Note: Nothing prevents you from using setNome , but the ideal and default .NET architecture is public string Nome {get ;set; } and being more readable is the default for any and all code. Example if you do the way setNome in ORM Entity Framework it will not consider.

    
27.05.2016 / 18:14