Как успешно хэшировать значения System.Windows.Input.Key с состояниями клавиш-модификаторов? - PullRequest
0 голосов
/ 03 февраля 2011

Я пытаюсь написать алгоритм хеширования, который успешно хеширует значения System.Windows.Input.Key с состояниями ключей модификатора, например:

ctrl = false
shift = true
alt = false
capslock = true
numlock = false
scroll lock = false
key: A

Таким образом, значение ключа, подобное этому, следует отделитьдругие с разными состояниями для ctrl, shift, alt и т. д. Но так как это просто true или false, я не уверен, как выделить его для значений хеша?

Есть идеи?Просто он должен быть достаточно уникальным, чтобы обрабатывать все возможные комбинации клавиш.

1 Ответ

1 голос
/ 03 февраля 2011

Я бы построил класс, содержащий все значения, способные вычислять его собственный хэш-код, например:

    class KeyInfo : IEquatable<KeyInfo>
    {
        public bool Ctrl { get; private set; }
        public bool Shift { get; private set; }
        public bool Alt { get; private set; }
        public bool CapsLock { get; private set; }
        public bool NumLock { get; private set; }
        public bool ScrollLock { get; private set; }
        public Keys Key { get; private set; }

        public KeyInfo(bool ctrl, bool shift, bool alt, bool capsLock, bool numLock, bool scrollLock, Keys key)
        {
            this.Ctrl = ctrl;
            this.Shift = shift;
            this.Alt = alt;
            this.CapsLock = capsLock;
            this.NumLock = numLock;
            this.ScrollLock = scrollLock;
            this.Key = key;
        }

        public override bool Equals(object obj)
        {
            return this.Equals(obj as KeyInfo);
        }

        public bool Equals(KeyInfo other)
        {
            if (other == null)
                return false;
            return this.Ctrl == other.Ctrl && this.Shift == other.Shift &&
                   this.Alt == other.Alt && this.CapsLock == other.CapsLock &&
                   this.NumLock == other.NumLock && this.ScrollLock == other.ScrollLock &&
                   this.Key == other.Key;
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hash = 17;
                hash = hash * 23 + this.Ctrl.GetHashCode();
                hash = hash * 23 + this.Shift.GetHashCode();
                hash = hash * 23 + this.Alt.GetHashCode();
                hash = hash * 23 + this.CapsLock.GetHashCode();
                hash = hash * 23 + this.NumLock.GetHashCode();
                hash = hash * 23 + this.ScrollLock.GetHashCode();
                hash = hash * 23 + this.Key.GetHashCode();
                return hash;
            }
        }
    }

Кредиты для ответа Джона Скита за реализацию GetHashCode().

Н.Б.

этот класс может эффективно использоваться в качестве клавиши Dictionary, в HashSet или в LINQ Distinct() и операциях других наборов LINQ.

EDIT:

Я бы хотел подчеркнуть тот факт, что вы не должны использовать хеш-код в качестве словарного ключа, но вместо этого используйте класс whole .
Вы не можете полагаться на уникальность хеш-кодов, потому что хэширование подвергается коллизиям .

...