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.