c# - 为什么当我调用此哈希集的删除操作时,它既不使用 gethashcode 也不使用相等实现?
问题描述
我正在做一个应用程序来管理角色扮演会话的创建,但是我在做规则摘要的部分有问题,所以大师不必每秒钟都阅读核心书,我有这种数据结构。
用户有一个活动列表,该活动有一个场景列表,而该场景有一个冒险列表。
用户 -> 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。
而且我不知道发生了什么。
我已将完整代码上传到 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 override bool Equals(object obj) {
if (!(obj is Resumenes)) return false;
var other = obj as Resumenes;
return this.Nombre.Equals(other.Nombre) && this.Descripcion.Equals(other.Descripcion);
}
public override int GetHashCode() {
return this.Nombre.GetHashCode();
}
请注意,这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() { ... }
}
推荐阅读
- linux - Google Cloud Compute Linux 实例:以 root 身份登录时无法使用浏览器下载文件?
- swift - 由于循环,Swift Completion Handler For Loop 将执行一次而不是 10 次
- javascript - 如何在 Javascript 中使用带函数表达式的变量提升?
- ios - CDN:运行“pod install”时,无法在某些 React Native 项目中下载主干 URL?
- python-3.x - Tkinter 对象未居中
- java - java - 如何使用weka api预测java中的多个属性?
- json - 将 JSON 动态解组为仅包含基于类型字段的顶级字段的结构
- c - 使用 AVX2 对带有十进制数字数组的 BigInt 进行矢量化随机初始化和打印?
- wordpress - 在dokan模板new-product.php添加图片上传自定义字段
- hibernate - 使用邮递员的@PostMapping 的某些值不受数据库影响(null 或 0 值)