gpt4 book ai didi

c# - WinForms:在基类中覆盖 GetHashCode 时绑定(bind)功能被破坏

转载 作者:行者123 更新时间:2023-11-30 20:20:22 25 4
gpt4 key购买 nike

我已将我的代码简化为以下重现错误的简短示例。我正在尝试将派生类的值绑定(bind)到控件。派生类和绑定(bind)逻辑为:

bindingSource = new BindingSource();
numericUpDown1.DataBindings.Add("Value", bindingSource, nameof(SinglePoint.Val), false, DataSourceUpdateMode.OnPropertyChanged);
bindingSource.DataSource = new[] { new SinglePoint(100) };
[...]
public class SinglePoint : PointList
{
public SinglePoint(int val) { points.Add(val); }
public int Val
{
get { return points[0]; }
set
{
if (value > 300) value = 300; //(*)
points[0] = value;
}
}
}

因此,当在 NumericUpDown 上设置例如值 500 时,在保留它之后我们应该看到 300,因为行 (*)。如果基类没有实现 GetHashCode,这会起作用:

public class PointList
{
protected List<int> points = new List<int>();
public PointList() { }
// UNCOMMENT this and the binding will stop working properly
//public override int GetHashCode()
//{
// unchecked
// {
// int hashCode = 17;
// foreach (var item in points)
// hashCode += 13 * item.GetHashCode();

// return hashCode;
// }
//}
}

但是,如果您尝试取消注释 GetHashCode 实现,绑定(bind)将会中断。这意味着在设置 500 并离开 NumericUpDown 后,控件仍将显示 500,但实际上基础值将是 300。为什么会发生这种情况以及如何在不关闭自定义实现的情况下解决它GetHashCode?

编辑

正如你们中的某些人所指出的,GetHashCode 不应更改,因为它已被绑定(bind)机制使用。这是对我问题第一部分的答复。但是,我怎样才能使我的 PointList 类满足其他 rule据此“如果两个事物相等 (Equals(...) == true),则它们必须为 GetHashCode() 返回相同的值”。如果我有两个具有相同点列表(序列)的 PointList 对象,我希望它们相等(因为我的代码中的其他逻辑),这应该意味着具有相同的哈希码。你会怎么做?

最佳答案

经验法则:

The integer returned by GetHashCode must never change while the object is contained in a data structure that depends on the hash code remaining stable

请参阅 Eric Lippert 的文章 here .

GetHashCode 中,您应该只使用只读或不可变字段;否则,该对象不能用于 DictionaryHashtable 和其他基于散列的集合。

关于c# - WinForms:在基类中覆盖 GetHashCode 时绑定(bind)功能被破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36937516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com