Reputation: 101
Hello I am new in C# and i have a little question :
when I call the method list1.contains(product)
is it like java we need to override the Equals method ?
if yes ? is this the way to do it ?
public partial class product
{
public product()
{
}
public int idProduct { get; set; }
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (this.GetType() != obj.GetType())
{
return false;
}
product other = (product)obj;
if (idProduct != other.idProduct)
{
return false;
}
return true;
}
}
Upvotes: 0
Views: 107
Reputation: 223187
In addition to @driis answer, you can also create a new IEqualityComparer<Product>
like:
public sealed class ProductEqualityComparer : IEqualityComparer<Product>
{
public bool Equals(Product x, Product y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
if (x.GetType() != y.GetType()) return false;
return x.idProduct == y.idProduct;
}
public int GetHashCode(Product obj)
{
return obj.idProduct;
}
}
And then you can pass that Comparer
to Contains
like:
if (list1.Contains(product, new ProductEqualityComparer()))
{
}
Where list1
is List<Product>
defined as:
Product product = new Product { idProduct = 1 };
List<Product> list1 = new List<Product>
{
new Product{idProduct = 1},
new Product{idProduct = 2}
};
Or you can inherit from EqualityComparer<T>
and then override Equals
and GetHashCode
, because MSDN states
We recommend that you derive from the
EqualityComparer<T>
class instead of implementing theIEqualityComparer<T>
interface, because theEqualityComparer<T>
class tests for equality using theIEquatable<T>.Equals
method instead of the Object.Equals method. This is consistent with the Contains, IndexOf, LastIndexOf, and Remove methods of theDictionary<TKey, TValue>
class and other generic collections.
public sealed class ProductEqualityComparer : EqualityComparer<Product>
{
public override bool Equals(Product x, Product y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
if (x.GetType() != y.GetType()) return false;
return x.idProduct == y.idProduct;
}
public override int GetHashCode(Product obj)
{
return obj.idProduct;
}
}
Upvotes: 1
Reputation: 126042
It's probably worth mentioning that you can shorten your code a bit by implementing IEquatable<T>
.
List<T>.Contains
will call IEquatable<T>.Equals
if the type in your generic list implements IEquatable
, avoiding the cast:
public class product : IEquatable<product>
{
public int idProduct { get; set; }
// List<product>.Contains will call IEquatable<product>.Equals if available.
public bool Equals(product other)
{
return ReferenceEquals(other, this) || other.idProduct == this.idProduct;
}
// Note: you should still override object.Equals.
public override bool Equals(object other)
{
return this.Equals(other as product);
}
}
Also in C# classes are typically PascalCased
and not camelCased
.
Upvotes: 0
Reputation: 164281
Yes, you should override Equals to provide equality semantics for your class. By default, reference equality will be in play.
Your Equals method will work, but in C# we can also override the == operator. Therefore, it might not be safe to use in an Equals method. It would be better to use ReferenceEquals
for the reference comparisons:
public override bool Equals(object obj)
{
if (ReferenceEquals(obj,null))
{
return false;
}
if (ReferenceEquals(this,obj))
{
return true;
}
if (this.GetType() != obj.GetType())
{
return false;
}
product other = (product)obj;
if (idProduct != other.idProduct)
{
return false;
}
return true;
}
Upvotes: 3