Consider the following:
class Bind
{
public string x { get; set; }
public string y { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ObservableCollection<Bind> cX = new ObservableCollection<Bind>();
ObservableCollection<Bind> cY = new ObservableCollection<Bind>();
cX.Add(new Bind { x = "a", y = "1" });
cX.Add(new Bind { x = "b", y = "2" });
cY.Add(new Bind { x = "a", y = "1" });
foreach (var i in cX)
{
if (!cY.Contains(i)) { lv.Items.Add(i); } //lv is a ListView control
}
}
}
Why does it add x = "a", y = "1" to the ListView?
If I change ObservableCollection to List or Collection, it does the same.
The ‘Contains’ method uses the Equals on object, and this simply checks that the memory addresses are different.
Consider changing your class to this…
Your loop will then visit the strongly typed Equals method in your class, and this will result in the behaviour you are after.
NOTE: the string class ALSO inherits from IEquatable of T and that is what allows the equality operator to operate on the content of the string rather than the address of the string.