Reputation: 468
I have a class as below. To an object of this class I need to add a new language in case it doesn't exist
using System;
using System.Collections.Generic;
namespace discovery.POCO
{
public class MultiLingualObject
{
public string TableName { get; set; }
public string BranchId { get; set; }
public int GenericId { get; set; }
public string GenericCode { get; set; }
public List<MultiLingualColumn> MultiLingColumnsCollection = new List<MultiLingualColumn>();
}
public class MultiLingualColumn : IEquatable<MultiLingualColumn>
{
public string ColumnName { get; set; }
public string LanguageCode { get; set; }
public string LanguageText { get; set; }
public bool Equals(MultiLingualColumn other)
{
if (other == null) return false;
return string.Equals(ColumnName,other.ColumnName) &&
string.Equals(LanguageCode, other.LanguageCode) &&
string.Equals(LanguageText, other.LanguageText);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals(obj as MultiLingualColumn);
}
}
}
As I am new to C# I have searched for various solutions, including .Contains or Equal (from where I have added override to my Equal above). I also understand I can achieve the comparison by simply using where like this. Yet, as I might have more elements added to the class, I would like to stick to either Equal or Contains, if possible. The code I use to compare and then to insert if doesn't exist is as following
internal void UpdateLocalMultiLing()
{
POCO.MultiLingualColumn _equals = new POCO.MultiLingualColumn()
{
ColumnName = InvoiceComment.Name.TrimEnd(),
LanguageCode = inputLanguage,
LanguageText = InvoiceComment.Value.TrimEnd()
};
if (!SupplierMultiLing.MultiLingColumnsCollection.Equals(_equals))
SupplierMultiLing.MultiLingColumnsCollection.Add(new POCO.MultiLingualColumn
{
ColumnName = InvoiceComment.Name.Trim(),
LanguageCode = inputLanguage,
LanguageText = InvoiceComment.Value.Trim()
}
);
}
yet it ignores the condition and adds the same language again. It can be seen from the image attached.
Can one advise what shall I fix, please?
Upvotes: 1
Views: 1607
Reputation: 1863
You should use the Contains()
method. Also you should implement IEquatable
interface for the MultiLingualColumn
or implement IEqualityComparer
and pass the second argument to Contains()
. I prefer the second option:
public class MultiLingualColumnComparer : IEqualityComparer<MultiLingualColumn>
{
public bool Equals(MultiLingualColumn x, MultiLingualColumn y)
{
//...
}
public int GetHashCode(MultiLingualColumn obj)
{
//...
}
}
and then:
if (!SupplierMultiLing.MultiLingColumnsCollection.Contains(_equals, new MultiLingualColumnComparer()))
Upvotes: 0
Reputation: 151594
You're comparing a list against a single object. You need .Contains()
instead of .Equals()
.
Either properly implement IEquatable<T>
, or override Equals(object)
and GetHashCode()
. From What does Collection.Contains() use to check for existing objects?:
either implement IEquatable on your custom class, or override the Equals (and GetHashCode)
This code prints "True":
public class Foo : IEquatable<Foo>
{
public string Bar { get; set; }
public bool Equals(Foo other)
{
return other.Bar == this.Bar;
}
}
public static void Main()
{
var list = new List<Foo>
{
new Foo { Bar = "Baz" }
};
Console.WriteLine(list.Contains(new Foo { Bar = "Baz" }));
}
But as @Jeppe correctly comments, it's advisable to also provide a proper implementation of GetHashCode()
for other collection and comparison types.
Upvotes: 4