【问题标题】:C# - How to override GetHashCode with Lists in objectC# - 如何用对象中的列表覆盖 GetHashCode
【发布时间】:2009-11-17 19:08:19
【问题描述】:

我正在尝试创建一个“KeySet”来修改 UIElement 行为。这个想法是创建一个特殊的功能,例如。用户在按住 a 的同时单击一个元素。或者 ctrl+a。

到目前为止,我的方法是,首先让我们为所有可能的修饰符创建一个容器。如果我只允许一个键,那将没有问题。我可以使用一个简单的字典,与

Dictionary<Keys, Action> _specialActionList
  • 如果字典为空,则使用默认操作。
  • 如果有条目,请根据当前按下的键检查要使用的操作

如果我不贪心,那就是…… 现在,当然,我想要更多。我想允许多个键或修饰符。所以我创建了一个包装类,它可以用作我的字典的键。

使用更复杂的类时有一个明显的问题。目前两个不同的实例会创建两个不同的键,因此他永远不会找到我的函数(看代码来理解,真的很明显)

现在我查看了这个帖子:GetHashCode override of object containing generic array,这有点帮助。

但我的问题是,我的课程的基本设计还可以吗?我应该使用哈希集来存储修饰符和普通键盘键(而不是列表)。如果是这样,GetHashCode 函数会是什么样子?

我知道,要编写很多代码(无聊的哈希函数),一些技巧足以让我开始。将在此处发布试用...

到目前为止的代码来了,测试显然失败了......

        public class KeyModifierSet
    {
        private readonly List<Key> _keys = new List<Key>();
        private readonly List<ModifierKeys> _modifierKeys = new List<ModifierKeys>();

        private static readonly Dictionary<KeyModifierSet, Action> _testDict 
                          = new Dictionary<KeyModifierSet, Action>();

        public static void Test()
        {
            _testDict.Add(new KeyModifierSet(Key.A), () => Debug.WriteLine("nothing"));
            if (!_testDict.ContainsKey(new KeyModifierSet(Key.A))) throw new Exception("Not done yet, help :-)");
        }

        public KeyModifierSet(IEnumerable<Key> keys, IEnumerable<ModifierKeys> modifierKeys)
        {
            foreach (var key in keys)
                _keys.Add(key);

            foreach (var key in modifierKeys)
                _modifierKeys.Add(key);
        }

        public KeyModifierSet(Key key, ModifierKeys modifierKey)
        {
            _keys.Add(key);
            _modifierKeys.Add(modifierKey);
        }

        public KeyModifierSet(Key key)
        {
            _keys.Add(key);
        }
    }

【问题讨论】:

  • 你在说什么编程语言?
  • 您可能需要添加一个标签来指示您所询问的语言。
  • 你的问题到底是什么!?

标签: c# equals gethashcode


【解决方案1】:
 _testDict.Add(new KeyModifierSet(Key.A), () => Debug.WriteLine("nothing"));
 if (!_testDict.ContainsKey(new KeyModifierSet(Key.A))) throw new Exception("Not done yet, help :-)");

如果我正确理解您的代码,您希望使用 Object.Equals 和 Object.GetHashCode 方法的覆盖版本来测试您的 _testDict Dictionary 对象是否相等。据我所知,您需要创建自己的自定义集合类型来覆盖这些方法。

【讨论】:

    【解决方案2】:

    要回答我自己的(提出的稍微复杂的)问题,以下是解决方案:

    public class KeyModifierSet
    {
        internal readonly HashSet<Key> Keys = new HashSet<Key>();
        internal readonly HashSet<ModifierKeys> MKeys = new HashSet<ModifierKeys>();
    
        public override int GetHashCode()
        {
            int hash = Keys.Count + MKeys.Count;
            foreach (var t in Keys)
            {
                hash *= 17;
                hash = hash + t.GetHashCode();
            }
            foreach (var t in MKeys)
            {
                hash *= 19;
                hash = hash + t.GetHashCode();
            }
            return hash;
        }
    
        public override bool Equals(object obj)
        {
            return Equals(obj as KeyModifierSet);
        }
        public bool Equals(KeyModifierSet other)
        {
            // Check for null
            if (ReferenceEquals(other, null))
                return false;
    
            // Check for same reference
            if (ReferenceEquals(this, other))
                return true;
    
            // Check for same Id and same Values
            return Keys.SetEquals(other.Keys) && MKeys.SetEquals(other.MKeys);
        }
    
    
    
        public KeyModifierSet(ModifierKeys mKey)
        {
            MKeys.Add(mKey);
        }
        public KeyModifierSet(Key key)
        {
            Keys.Add(key);
        }
        public KeyModifierSet(Key key, ModifierKeys mKey)
        {
            Keys.Add(key);
            MKeys.Add(mKey);
        }
        public KeyModifierSet Add(Key key)
        {
            Keys.Add(key);
            return this;
        }
        public KeyModifierSet Add(ModifierKeys key)
        {
            MKeys.Add(key);
            return this;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-13
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 1970-01-01
      • 2011-05-13
      相关资源
      最近更新 更多