Мультиключевой словарь в c#? [дубликат]

Можно добавить события к объектам при создании их. Если Вы добавляете, что те же события к нескольким объектам в разное время, создавая именованную функцию могли бы быть способом пойти.

var mouseOverHandler = function() {
    // Do stuff
};
var mouseOutHandler = function () {
    // Do stuff
};

$(function() {
    // On the document load, apply to existing elements
    $('select').hover(mouseOverHandler, mouseOutHandler);
});

// This next part would be in the callback from your Ajax call
$("<select></select>")
    .append( /* Your <option>s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )
;
112
задан Jegadeesh 18 March 2014 в 17:47
поделиться

10 ответов

Я также использовал кортежи, как Джейсон в своем ответе . Однако я предлагаю вам просто определить кортеж как структуру:

public struct Tuple<T1, T2> {
    public readonly T1 Item1;
    public readonly T2 Item2;
    public Tuple(T1 item1, T2 item2) { Item1 = item1; Item2 = item2;} 
}

public static class Tuple { // for type-inference goodness.
    public static Tuple<T1,T2> Create<T1,T2>(T1 item1, T2 item2) { 
        return new Tuple<T1,T2>(item1, item2); 
    }
}

Вы получаете неизменяемость, .GetHashcode и .Equals бесплатно, что (пока вы ждете C # 4.0 ) красиво и просто ...

Одно предупреждение однако: реализация по умолчанию GetHashcode (иногда) учитывает только первое поле , поэтому убедитесь, что сделайте первое поле наиболее разборчивым или реализуйте GetHashcode самостоятельно (например, используя FieldwiseHasher.Hash (this) из ValueUtils ), иначе вы, скорее всего, столкнетесь с масштабируемостью

Кроме того, вы можете избежать нулей, которые могут усложнить ситуацию (и если вам действительно нужны нули, вы просто делаете свой Tuple <> обнуляемым). Немного оффтоп, я единственный, кого раздражает отсутствие поддержки ненулевых ссылок на уровне фреймворка? Я работаю над большим проектом, и иногда ноль закрадывается туда, где этого действительно не должно быть - и, эй, престо, вы получаете исключение с нулевой ссылкой - но с трассировкой стека, которая указывает на первое использование ссылки, а не на действительно ошибочный код .

Конечно, .NET 4.0 уже устарела; большинство из нас может просто использовать кортеж .NET 4.0.

Изменить: для обхода плохой реализации GetHashCode , которую .NET предоставляет для структур, которые я написал ValueUtils , что также позволяет использовать настоящие имена для многополевых ключей; это означает, что вы можете написать что-то вроде:

sealed class MyValueObject : ValueObject<MyValueObject> {
    public DayOfWeek day;
    public string NamedPart;
    //properties work fine too
}

... что, мы надеемся, упрощает создание удобочитаемых имен для данных с семантикой значений, по крайней мере, до тех пор, пока в какой-то будущей версии C # не будут реализованы правильные кортежи с именованными членами ; надеюсь, с приличными хэш-кодами; -).

65
ответ дан 24 November 2019 в 02:50
поделиться

Вот конкретный пример парного класса, который можно использовать как ключ к словарю.

  public class Pair<T1, T2> {
    public T1 Left { get; private set; }
    public T2 Right { get; private set; }

    public Pair(T1 t1, T2 t2) {
      Left=t1;
      Right=t2;
    }

    public override bool Equals(object obj) {
      if(ReferenceEquals(null, obj)) return false;
      if(ReferenceEquals(this, obj)) return true;
      if(obj.GetType()!=typeof(Pair<T1, T2>)) return false;
      return Equals((Pair<T1, T2>)obj);
    }

    public bool Equals(Pair<T1, T2> obj) {
      if(ReferenceEquals(null, obj)) return false;
      if(ReferenceEquals(this, obj)) return true;
      return Equals(obj.Left, Left) && Equals(obj.Right, Right);
    }

    public override int GetHashCode() {
      unchecked {
        return (Left.GetHashCode()*397)^Right.GetHashCode();
      }
    }
  }
2
ответ дан 24 November 2019 в 02:50
поделиться

Не могли бы вы использовать Dictionary > ?

Вы могли бы даже подклассифицировать это:

public class DualKeyDictionary<TKey1,TKey2,TValue> : Dictionary<TKey1,Dictionary<TKey2,TValue>>

EDIT: Это теперь дублированный ответ. Он также ограничен в своей практичности. Хотя он «работает» и обеспечивает возможность кодирования dict [key1] [key2] , существует множество «обходных путей», чтобы заставить его «просто работать».

ОДНАКО: Просто для удовольствия, можно, тем не менее, реализовать Dictionary, но на этом этапе он становится немного подробным:

public class DualKeyDictionary<TKey1, TKey2, TValue> : Dictionary<TKey1, Dictionary<TKey2, TValue>> , IDictionary< object[], TValue >
{
    #region IDictionary<object[],TValue> Members

    void IDictionary<object[], TValue>.Add( object[] key, TValue value )
    {
        if ( key == null || key.Length != 2 )
            throw new ArgumentException( "Invalid Key" );

        TKey1 key1 = key[0] as TKey1;
        TKey2 key2 = key[1] as TKey2;

        if ( !ContainsKey( key1 ) )
            Add( key1, new Dictionary<TKey2, TValue>() );

        this[key1][key2] = value;
    }

    bool IDictionary<object[], TValue>.ContainsKey( object[] key )
    {
        if ( key == null || key.Length != 2 )
            throw new ArgumentException( "Invalid Key" );

        TKey1 key1 = key[0] as TKey1;
        TKey2 key2 = key[1] as TKey2;

        if ( !ContainsKey( key1 ) )
            return false;

        if ( !this[key1].ContainsKey( key2 ) )
            return false;

        return true;
    }
2
ответ дан 24 November 2019 в 02:50
поделиться

Думаю, вам понадобится класс типа Tuple2. Убедитесь, что GetHashCode () и Equals () основаны на двух содержащихся элементах.

См. Кортежи в C #

2
ответ дан 24 November 2019 в 02:50
поделиться

Я поискал в Google вот это: http://www.codeproject.com/KB/recipes/multikey-dictionary.aspx . Я полагаю, что его главная особенность по сравнению с использованием структуры, содержащей 2 ключа в обычном словаре, заключается в том, что вы можете позже ссылаться на один из ключей вместо того, чтобы указывать 2 ключа.

4
ответ дан 24 November 2019 в 02:50
поделиться

Что-то не так с

new Dictionary<KeyValuePair<object, object>, object>
?
6
ответ дан 24 November 2019 в 02:50
поделиться

Возьмите взгляните на Wintellect PowerCollections ( загрузка CodePlex ). Я думаю, что их MultiDictionary делает что-то подобное.

Это словарь словарей, поэтому у вас есть 2 ключа для доступа к каждому объекту, ключ для основного словаря, чтобы получить требуемый вспомогательный словарь, а затем второй ключ для вспомогательного словаря, чтобы получить требуемый элемент. Вы это имеете в виду?

6
ответ дан 24 November 2019 в 02:50
поделиться

В настоящее время я просто объединяю ключи в одну строку в качестве обходного пути. Конечно, это не будет работать с нестроковыми ключами. Также хотелось бы узнать ответ.

7
ответ дан 24 November 2019 в 02:50
поделиться

Кортежи будут (есть) в .Net 4.0. До тех пор вы также можете использовать

 Dictionary<key1, Dictionary<key2, TypeObject>> 

или, создав собственный класс коллекции для представления этого ...

 public class TwoKeyDictionary<K1, K2, T>: 
        Dictionary<K1, Dictionary<K2, T>> { }

или, с три клавиши ...

public class ThreeKeyDictionary<K1, K2, K3, T> :
    Dictionary<K1, Dictionary<K2, Dictionary<K3, T>>> { }
32
ответ дан 24 November 2019 в 02:50
поделиться

Я использую кортеж в качестве ключей в Словаре .

public class Tuple<T1, T2> {
    public T1 Item1 { get; private set; }
    public T2 Item2 { get; private set; }

    // implementation details
}

Не забудьте переопределить Equals и ] GetHashCode и определите operator! = и operator == в зависимости от ситуации. Вы можете расширить кортеж , чтобы вместить больше элементов по мере необходимости. .NET 4.0 будет включать встроенный кортеж .

54
ответ дан 24 November 2019 в 02:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: