我在C#工作。我想从ObservableCollection<Catalog>
删除目录(我之前定义的对象类型)。
我知道当您致电Remove
,Contains
或Add
时... 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类型)时,我会在以下行中获得InvalidCastException
:Catalog cat = (Catalog)obj
。
为什么在这里投无效?为什么不在这里调用Equals(Catalog cat)而不是Equals(object obj)定义?
当然,Remove
不起作用,即使Console.WriteLine(myCollection.Contains(catlg))
为真。
答案 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();
}