Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# для начинающих

Войти
Регистрация
Восстановить пароль
 
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
#1

Dictionary с адресами классов в качестве ключей - C#

24.07.2013, 19:09. Просмотров 705. Ответов 14
Метки нет (Все метки)

Предположим есть такой код:
C#
1
MyClass x, y;
У класса MyClass есть конструктор по умолчанию, так что x и y равны. Я хочу, чтобы выполнялось условие:
C#
1
2
3
Dictionary <MyClass, int> m;
...
if (m[x] != m[y])..
То есть, я хочу, чтобы в качестве включа словаря использовались ссылки на объекты, и условие выглядело фактически m[0x183AF9] != m[0x183AFF]
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.07.2013, 19:09
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Dictionary с адресами классов в качестве ключей (C#):

Поиск ключей и данных в коллекции Dictionary - C#
Здравствуйте. Есть коллекция типа Dictionary с именем _Data типа &lt;string, string&gt;. Так же есть переменные типа string с именем _Char,...

.NET 4.x Извлечь массив значений из Dictionary с помощью массива ключей - C#
Как можно извлечь из экземпляра Dictionary массив значений при помощи имеющегося массива соответствующих ключей?

Нужно пройтись по списку ключей Dictionary и записать их через запятую - C#
Нужно как то упростить мой быдлокод) int i = 0; string homesName = string.Empty; foreach(var h in Homes) { if(i != 0)...

Как получить строковое представление ключей и значений из коллекции Dictionary - C#
Как получить строковое представление значений ключе я значений из коллекции Dictionary

Массив в качестве значения в dictionary - C#
Здравствуйте, господа программисты. прошу вашей помощи. Имею следующую конструкцию Dictionary&lt;Id, Char&gt; Ids = new Dictionary&lt;Id,...

Задачи на наследование классов, в которых данные описаны в качестве свойств - C#
Создать класс Money для работы с денежными суммами в котором для рублей и копеек предусмотрены независимые целочисленные данные....

14
turbanoff
Модератор
Эксперт Java
3973 / 3708 / 460
Регистрация: 18.05.2010
Сообщений: 9,286
Записей в блоге: 11
Завершенные тесты: 1
24.07.2013, 20:43 #2
Цитата Сообщение от nexen Посмотреть сообщение
У класса MyClass есть конструктор по умолчанию, так что x и y равны.
Странное утверждение, учитывая что вы не вызываете конструктор, и то что конструктор всегда создает новый объект.
0
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
24.07.2013, 20:46  [ТС] #3
turbanoff, ну это я уже от С++ взял случайно Представьте, что там x = new MyClass(), y = new MyClass()
0
turbanoff
Модератор
Эксперт Java
3973 / 3708 / 460
Регистрация: 18.05.2010
Сообщений: 9,286
Записей в блоге: 11
Завершенные тесты: 1
24.07.2013, 20:50 #4
У конструктора Dictionary есть параметр, который позволяет использовать свой способ сравнения объектов.
Можно его реализовать, например, так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
class ReferenceEqualityComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y)
    {
        return object.ReferenceEquals(x, y);
    }
 
    public int GetHashCode(T obj)
    {
        return RuntimeHelpers.GetHashCode(obj);
    }
}
C#
1
2
var eqComparer = new ReferenceEqualityComparer<MyClass>();
Dictionary<MyClass, int> m = new Dictionary<MyClass, int>(eqComparer);
Теперь, какие бы объекты вы не ложили в словарь, они всегда будут сравниваться по ссылкам.
0
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
24.07.2013, 21:44  [ТС] #5
turbanoff, а зачем перегружать метод с получением хэша?
0
Psilon
Master of Orion
Эксперт .NET
5908 / 4805 / 634
Регистрация: 10.07.2011
Сообщений: 14,407
Записей в блоге: 5
Завершенные тесты: 4
24.07.2013, 21:49 #6
nexen, потому что словарь сначала проверяет равенство хеша, если они не совпадают - то проверять дальше смысла нету - объекты разные. Если же совпадают, тогда начинается более глубокая проверка. Во-первых хэш высчитывается один раз, во-вторых он затем складывается в скрытое поле класса, откуда получается при последующих запросах без новых вычислений. Таким образом достигается неплохой буст производительности.
1
turbanoff
Модератор
Эксперт Java
3973 / 3708 / 460
Регистрация: 18.05.2010
Сообщений: 9,286
Записей в блоге: 11
Завершенные тесты: 1
24.07.2013, 21:58 #7
Цитата Сообщение от Psilon Посмотреть сообщение
Во-первых хэш высчитывается один раз, во-вторых он затем складывается в скрытое поле класса
Даже сторонний хэш, как в моем примере?

Добавлено через 1 минуту
Цитата Сообщение от nexen Посмотреть сообщение
а зачем перегружать метод с получением хэша?
Этого требует интерфейс IEqualityComparer<T>
1
Psilon
Master of Orion
Эксперт .NET
5908 / 4805 / 634
Регистрация: 10.07.2011
Сообщений: 14,407
Записей в блоге: 5
Завершенные тесты: 4
24.07.2013, 22:03 #8
turbanoff, в данном случае я ответил на следующий по логике вопрос, зачем обязательно его переопределять.

Поищу пруфы пока, если нужно.

Добавлено через 2 минуты
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
private void Insert(TKey key, TValue value, bool add)
    {
      if ((object) key == null)
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
      if (this.buckets == null)
        this.Initialize(0);
      int num1 = this.comparer.GetHashCode(key) & int.MaxValue;
      int index1 = num1 % this.buckets.Length;
      int num2 = 0;
      for (int index2 = this.buckets[index1]; index2 >= 0; index2 = this.entries[index2].next)
      {
        if (this.entries[index2].hashCode == num1 && this.comparer.Equals(this.entries[index2].key, key))
        {
          if (add)
            ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
          this.entries[index2].value = value;
          ++this.version;
          return;
        }
        else
          ++num2;
      }
      int index3;
      if (this.freeCount > 0)
      {
        index3 = this.freeList;
        this.freeList = this.entries[index3].next;
        --this.freeCount;
      }
      else
      {
        if (this.count == this.entries.Length)
        {
          this.Resize();
          index1 = num1 % this.buckets.Length;
        }
        index3 = this.count;
        ++this.count;
      }
      this.entries[index3].hashCode = num1;
      this.entries[index3].next = this.buckets[index1];
      this.entries[index3].key = key;
      this.entries[index3].value = value;
      this.buckets[index1] = index3;
      ++this.version;
      if (num2 <= 100 || !HashHelpers.IsWellKnownEqualityComparer((object) this.comparer))
        return;
      this.comparer = (IEqualityComparer<TKey>) HashHelpers.GetRandomizedEqualityComparer((object) this.comparer);
      this.Resize(this.entries.Length, true);
    }
1
turbanoff
Модератор
Эксперт Java
3973 / 3708 / 460
Регистрация: 18.05.2010
Сообщений: 9,286
Записей в блоге: 11
Завершенные тесты: 1
24.07.2013, 22:03 #9
Цитата Сообщение от Psilon Посмотреть сообщение
Поищу пруфы пока, если нужно.
Да не нужно. Я твердо знаю, что в скрытых полях классах не сохранить все хэши посчитанные сторонними IEqualityComparer-ами.
1
Psilon
Master of Orion
Эксперт .NET
5908 / 4805 / 634
Регистрация: 10.07.2011
Сообщений: 14,407
Записей в блоге: 5
Завершенные тесты: 4
24.07.2013, 22:05 #10
turbanoff, в поле естественно сохраняется только посчитанное самим объектом GetHashCode, а не сторонним, но в остальном механизм тот же.
1
turbanoff
Модератор
Эксперт Java
3973 / 3708 / 460
Регистрация: 18.05.2010
Сообщений: 9,286
Записей в блоге: 11
Завершенные тесты: 1
24.07.2013, 22:06 #11
Цитата Сообщение от Psilon Посмотреть сообщение
в остальном механизм тот же.
В смысле тот-же? Считается один раз? Или сохраняется в поле класса?
1
Psilon
Master of Orion
Эксперт .NET
5908 / 4805 / 634
Регистрация: 10.07.2011
Сообщений: 14,407
Записей в блоге: 5
Завершенные тесты: 4
24.07.2013, 22:07 #12
turbanoff, в смысле используется в качестве первого приближения равенства объектов.
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
25.07.2013, 07:46  [ТС] #13
А разве нормально хэш подсчитается от кастомного класса?

И всё же зачем мне кэш, если у меня сравниваются адреса? То же самое, что вместое сравнения int1 и int2 произвести сравниение: Equal(Hash(int1), Hash(int2)); - два раза считается ненужный хэш, ведь он так же равен типу int
0
turbanoff
Модератор
Эксперт Java
3973 / 3708 / 460
Регистрация: 18.05.2010
Сообщений: 9,286
Записей в блоге: 11
Завершенные тесты: 1
25.07.2013, 08:01 #14
nexen, Прочитайте описание RuntimeHelpers.GetHashCode
RuntimeHelpers.GetHashCode полезен в скриптах, в которых важна идентификация объекта. Для двух строк с идентичным содержимым метод RuntimeHelpers.GetHashCode вернет различные значения, так как они являются разными строковыми объектами, хотя и с одинаковым содержимым.
1
MrCold
855 / 753 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
25.07.2013, 09:25 #15
Цитата Сообщение от nexen Посмотреть сообщение
если у меня сравниваются адреса?
Какие могут быть адреса ? Сборка мусора и уплотнение памяти же ...
0
25.07.2013, 09:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.07.2013, 09:25
Привет! Вот еще темы с ответами:

Задачи на использование классов и объектов, в которых данные описаны в качестве свойств - C#
Круг на плоскости имеет координаты центра x0,y0 - вещественные свойства. Радиус круга r0 - также задан вещественным свойством. Реализовать...

Генерация и проверка на работоспособность ключей активации (регистрационных ключей) - C#
Помогите придумать как можно осуществить сие деяние. Суть заключается в чем, первая программа генерирует уникальные ключи по определенному...

Написать программу для функции, которая будет получать в качестве параметра объект одного из классов - C#
Нужно написать программу для функции, которая будет получать в качестве параметра объект одного из классов CupOfCoffee или CupOfTea. Далее...

Сложный Dictionary<MyClass, Dictionary<List<MyClass2>, List<string>>> MyDictionary - C#
Здравствуйте. Помогите plz реализовать обращения к словарю вида : Dictionary&lt;MyClass, Dictionary&lt;List&lt;MyClass2&gt;, List&lt;string&gt;&gt;&gt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru