为什么当我调用这个hashset的remove操作时,它既不使用gethashcode也不使用等式实现?
c#
我正在做一个应用程序来管理角色扮演会话的创建,但是我在做规则摘要的部分有问题,所以大师不必每秒钟都阅读核心书,我有这种方式的数据结构。
用户有一个战役列表,该战役有一个场景列表,场景有一个冒险列表。
用户 -> Lcampaings -> Lscenaries -> Ladventures
每个活动、场景或冒险都有资源,其中包含文档、图像、资源等列表以及摘要的散列集。
战役/场景/冒险 -> 资源 -> Ldocuments/LImages/.../HashSet 摘要
好的,所以为了修改我已经实现的等式和 gethashcode 的摘要
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Windows;
namespace ElEscribaDelDJ.Classes
{
public class Resumenes: INotifyPropertyChanged, IEqualityComparer<Resumenes>
{
private string _nombre;
public string Nombre
{
get { return _nombre; }
set {
_nombre = value;
OnPropertyChanged("Nombre");
}
}
private string _etiquetas;
public string Etiquetas
{
get { return _etiquetas; }
set {
_etiquetas = value;
OnPropertyChanged("Etiquetas");
}
}
private string _descripcion;
public string Descripcion
{
get { return _descripcion; }
set {
_descripcion = value;
OnPropertyChanged("Descripcion");
}
}
private int _pagina;
public int Pagina
{
get { return _pagina; }
set {
if (value <= 0)
_pagina = 1;
else
_pagina = value;
OnPropertyChanged("Pagina");
}
}
private string _manual;
public string Manual
{
get { return _manual; }
set {
_manual = value;
OnPropertyChanged("Manual");
}
}
private string _manualurl;
public string ManualUrl
{
get { return _manualurl; }
set
{
_manualurl = value;
OnPropertyChanged("ManualUrl");
}
}
private string _tipoaventura;
public string TipoAventura
{
get { return _tipoaventura; }
set {
_tipoaventura = value;
OnPropertyChanged("TipoAventura");
}
}
private string _nombretipoaventura;
public string NombreTipoAventura
{
get { return _nombretipoaventura; }
set {
_nombretipoaventura = value;
OnPropertyChanged("NombreTipoAventura");
}
}
private int _indice;
public int Indice
{
get { return _indice; }
set
{
_indice = value;
OnPropertyChanged("Indice");
}
}
private List<int> _indiceslibres;
public List<int> IndicesLibres
{
get { return _indiceslibres; }
set
{
_indiceslibres = value;
OnPropertyChanged("IndicesLibres");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
public bool Equals(Resumenes x, Resumenes y)
{
if (x.Nombre.Equals(y.Nombre) && x.Descripcion.Equals(y.Descripcion))
return true;
else
return false;
}
public int GetHashCode(Resumenes obj)
{
MessageBox.Show("El Hash code es " + obj.Nombre.GetHashCode());
return obj.Nombre.GetHashCode();
}
public Resumenes CopiarValores ()
{
return (Resumenes)this.MemberwiseClone();
}
}
}
(在 gethashcode 我有消息框只是为了知道是否被称为 ofc 我知道它不应该在那里)
我使用两个对象的名称和描述来了解它们是否相等,并使用 gethashcode 名称。
在阅读了很多关于哈希码和相等性如何工作的问题后,我做了这个,hashcodeA == hashcodeB 意味着它们可以相等,所以名称看起来很适合这个,这就是为什么我在相等时也使用描述,因为如果你有相同的名字和相同的描述,其大致相同的摘要。
好的,所以我显示所有摘要的列表,用户选择一个,单击编辑,在添加或编辑窗口中,我不在对象的深层复制中,然后我调用例如活动编辑摘要,在那里我删除旧对象并添加新对象,因为我读到如果您修改了用于制作哈希码的字段,那是最好的方法。
public void EditarResumen(Resumenes resumenviejo, Resumenes resumennuevo)
{
DatosAplicacion.CampanaSeleccionada.Recursos.Resumenes.Remove(resumenviejo);
DatosAplicacion.CampanaSeleccionada.Recursos.Resumenes.Add(resumennuevo);
RecursosAplicacion.SesionUsuario.ReemplazarCampana();
}
“Datosaplicacion”是一个静态类,其中包含用户从所有这些中选择的运动、场景和冒险
using System;
using System.Collections.Generic;
using System.Text;
namespace ElEscribaDelDJ.Classes.Utilidades.Aplicacion
{
public static class DatosAplicacion
{
private static Campana _campana = new Campana();
public static Campana CampanaSeleccionada
{
get { return _campana; }
set { _campana = value; }
}
public static int IndiceCampana;
private static EscenarioCampana _escenarioseleccionado = new EscenarioCampana();
public static EscenarioCampana EscenarioSeleccionado
{
get { return _escenarioseleccionado; }
set { _escenarioseleccionado = value; }
}
public static int IndiceEscenario;
private static Aventura _aventuraseleccionada;
public static Aventura AventuraSeleccionada
{
get { return _aventuraseleccionada; }
set { _aventuraseleccionada = value; }
}
public static int IndiceAventuraSeleccionada;
}
}
resumenviejo (oldsummary) 是用
public Resumenes CopiarValores ()
{
return (Resumenes)this.MemberwiseClone();
}
这应该没问题,因为我没有任何参考对象或类似对象。
但是当我调试应用程序时,删除操作总是抛出错误,并且从不调用相等操作和 gethashcode。
我不知道发生了什么。
我用这篇文章来做操作https://dotnetcodr.com/2017/01/12/how-to-check-whether-two-hashsets-are-equal-in-c-net-2/#:~: text=两个%20HashSet%20objects%20in%20C#,他们的%20order%20in%20the%20collection。
我已将完整代码上传到 github https://github.com/davidgmd/Proyecto-de-fin-de-grado
回答
你有两种方法GetHashCode和Equals
public bool Equals(Resumenes x, Resumenes y)
public int GetHashCode(Resumenes obj)
public bool Equals(Resumenes x, Resumenes y)
public int GetHashCode(Resumenes obj)
但是它们不会覆盖框架中的正确方法,因此不会被调用。您必须将以下内容覆盖为方法,以便框架使用它们
请注意,这this并不是真正需要的。只是为了澄清this实例与other传入的对象进行比较。
编辑
您可以使用您的覆盖,IEqualityComparer<Resumenes>但随后您必须将其传递给哈希集的构造函数。但是对于您放入 HashSet 的数据对象来实现IEqualityComparer. 更好的是你Resumenes应该实现IEquatable<T>接口
public class Resumenes: INotifyPropertyChanged, IEquatable<Resumenes> {
public override bool Equals(object obj) { ... }
public bool Equals(Resumenes other) { ... }
public override int GetHashCode() { ... }
}