即使对象在列表中,ObservableCollection.Remove也不起作用

时间:2014-04-28 08:51:23

标签: c# observablecollection

我在C#工作。我想从ObservableCollection<Catalog>删除目录(我之前定义的对象类型)。

我知道当您致电RemoveContainsAdd时... VM会调用Equals来“定位”您要添加或删除的对象。这是我的Catalog.Equals定义:

public override bool Equals(object obj) 
{
    Catalog cat = (Catalog)obj;
    return (this.Name.Equals(cat.Name));           
}

public bool Equals(Catalog cat)
{
    return (this.Name.Equals(cat.Name));
}

但是当我执行myCollection.Remove(catlg)(catlg属于Catalog类型)时,我会在以下行中获得InvalidCastExceptionCatalog cat = (Catalog)obj

为什么在这里投无效?为什么不在这里调用Equals(Catalog cat)而不是Equals(object obj)定义?

当然,Remove不起作用,即使Console.WriteLine(myCollection.Contains(catlg))为真。

4 个答案:

答案 0 :(得分:1)

尝试实施IEquatable<Catalog>

然后摆脱override

答案 1 :(得分:0)

一种解决方案可能是使用linq扩展方法。

var catalogToRemove = Catalogs.Single(p => p.Name == catalogName);
Catalogs.Remove(catalogToRemove);

另一个可能是实现IEquatable

public class Catalog : IEquatable<Catalog>
{
    public string Name { get; set; }

    public bool Equals(Catalog other)
    {
        return Name == other.Name;
    }
}

如果您没有要删除的确切对象,则第二次闷热很好。 例如,您可以创建一个新的Catalog对象,将名称设置为要删除的对象,并在集合的Remove方法中使用该新对象。如果你没有实现IEquatable,那么这将无法工作,因为新对象与集合中包含的对象不完全相同。

答案 2 :(得分:0)

由于您没有实现IEquatable,因此Remove方法的默认设置是使用Object.Equals方法,而不是您的通用Equals(Catalog);

这是IList.Remove的文档说明:

  

如果类型T实现 IEquatable 泛型接口,则相等   comparer是该接口的Equals方法;否则,   默认相等 comparer是Object.Equals。

这是MSDN文档中有关IEquatable<T>.Equals

的说明
  

如果实现Equals,则还应覆盖基类   Object.Equals(Object)和GetHashCode的实现使他们的   行为与IEquatable.Equals方法的行为一致。   如果你覆盖了Object.Equals(Object),你的覆盖   在调用static时也会调用实现   您的类上的 Equals(System.Object,System.Object)方法。在   另外,你应该重载

在您的代码中某处可能存在比较,其中Equals(object)通过Catalog调用另一个不是Equals(System.Object, System.Object)的类型,这会导致InvalidOperationException。

使用as关键字代替显式广告,并确保实施IEquatable<Catalog>

public override bool Equals(object obj) 
{
    Catalog cat = obj as Catalog;
    if (cat == null)
    {
       return;
    }
    return (this.Name.Equals(cat.Name));           
}

答案 3 :(得分:0)

您必须实施GetHashCode(link

public override bool Equals(object obj) 
{
    Catalog cat =  obj as Catalog;
    if (cat == null)
    {
        return false;
    }

    return (this.Name.Equals(cat.Name));           
}

我使用的是与你不同的演员。使用as,您可以检查它是否正确。

public bool Equals(Catalog cat)
{
    return (this.Name.Equals(cat.Name));
}

public int GetHashCode(object obj)
{
    // implement your hash code logic here
    return obj.ToString().GetHashCode();
}