Оффтопик. Изучаем C#

Автор Тема: Оффтопик. Изучаем C#  (Прочитано 244172 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Мурена

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 0
Re: Оффтопик. Изучаем C#
« Ответ #150 : 27-12-2017, 15:40:47 »
Здравствуйте!
Подскажите, пожалуйста, если использовать сначала Dictionary.ContainsKey(key), а потом Dictionary.Add(key,value) не происходит ли двойной поиск  ключа в словаре? или Add не проверяет?

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Оффтопик. Изучаем C#
« Ответ #151 : 27-12-2017, 15:46:05 »
или Add не проверяет?
Add выдаёт исключение, если такой ключ уже есть.
Я в последнее время практически не использую этот метод, как раз из-за того, что нужно сперва проверять наличие ключа. Мне проще так:
Код - C# [Выбрать]
  1. Dictionary<string, int> dict = new Dictionary<string, int>();
  2.  
  3. // Вместо такой конструкции
  4. if (!dict.ContainsKey("item"))
  5. {
  6.     dict.Add("item", 0);
  7. }
  8.  
  9. // Можно написать просто так
  10. dict["item"] = 0;
  11. // Если значение есть, то оно перезапишется. Если нет - создастся новое.
  12. // В большинстве случаев меня такое поведение полностью устраивает
  13.  

Оффлайн Мурена

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 0
Re: Оффтопик. Изучаем C#
« Ответ #152 : 27-12-2017, 15:47:52 »
Мне не надо перезаписывать, а наоборот, если есть , то вернуть , что есть, если нет - то записать

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Оффтопик. Изучаем C#
« Ответ #153 : 27-12-2017, 15:53:30 »
Мне не надо перезаписывать, а наоборот, если есть , то вернуть , что есть, если нет - то записать
Тогда еще проще:
Код - C# [Выбрать]
  1.     Dictionary<string, int> dict = new Dictionary<string, int>();
  2.      
  3.     if (!dict.ContainsKey("item"))
  4.     {
  5.         dict.Add("item", 0);
  6.     }
  7.      
  8.     return dict["item"];
     
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Оффтопик. Изучаем C#
« Ответ #154 : 27-12-2017, 15:54:26 »
Ну тогда через ContainsKey и Add - самое разумное. Фактически, да, происходит двойная проверка по коллекции ключей: https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/collections/generic/dictionary.cs

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Оффтопик. Изучаем C#
« Ответ #155 : 27-12-2017, 15:58:36 »
не происходит ли двойной поиск  ключа в словаре?
Так как коллекция упорядоченная, то поиск происходит очень быстро (не последовательным перебором). Так что об этом можно не беспокоиться.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Мурена

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 0
Re: Оффтопик. Изучаем C#
« Ответ #156 : 27-12-2017, 16:05:34 »
Так как коллекция упорядоченная, то поиск происходит очень быстро (не последовательным перебором). Так что об этом можно не беспокоиться.
Вот тут , пожалуйста, поподробней.
Итак, сравнение ключей всё же происходит дважды.

Но, я, как обычно, что то перемудрила, наверно, и пока у меня так:
Код - C# [Выбрать]
  1. class MyCmparer : EqualityComparer<GeometryClass>
  2.     {
  3.         public override bool Equals(GeometryClass x, GeometryClass y)
  4.         {
  5.             if (x == y) { return true; }
  6.             if (x == null || y == null) { return false; }
  7.             if (x.IdentClass != y.IdentClass) { return false; }
  8.  
  9.             return x.Equals(y);
  10.         }
  11.        
  12.         public override int GetHashCode(GeometryClass source) //Переопределяя иквалс, переопредели и гетхешкод
  13.         {
  14. //тут будет код
  15.         }
  16.  
  17.     }
  18.  
  19.  
  20.     interface IGeometry
  21.     {
  22.     }
  23.  
  24.     abstract class GeometryClass : IGeometry, IEquatable <GeometryClass>
  25.     {
  26.         //данные для построения каркасса СБН
  27.         String identClass; // идентификатор конструкции
  28.         internal String IdentClass { get { return identClass; } }
  29.         internal GeometryClass(String value)
  30.         {
  31.             identClass = value;
  32.         }
  33.         public abstract Boolean IEquatable<GeometryClass>.Equals(GeometryClass other);
  34.        
  35.     }

Идей в том, чтобы передать сравнение экземпляров их классам, где метод Equals переопределён так, как мне надо. Код разрабатывается в данный момент ещё не проверялся
« Последнее редактирование: 27-12-2017, 16:12:56 от Александр Ривилис »

Оффлайн Мурена

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 0
Re: Оффтопик. Изучаем C#
« Ответ #157 : 27-12-2017, 16:14:19 »
Код - C# [Выбрать]
  1. class DataBaseConcreteProducts // хранит ссылки на экземпляры дерева в хештаблицах в общей базе
  2.     {
  3.         //сделать синглтоном
  4.         private static DataBaseConcreteProducts instance; //ссылка на экземпляр , принадлежит сформированному объекту (т.е. при создании экземпляра будет инициализировано поле объекта)
  5.         internal static DataBaseConcreteProducts GetDataBase() //метод для создания единственного объекта
  6.         {
  7.             if (instance != null)
  8.             { instance = new DataBaseConcreteProducts(); }
  9.             return instance;
  10.  
  11.         }
  12.         Dictionary<GeometryClass, Object > dataBase;
  13.         internal Dictionary<GeometryClass, Object> DataBase { get { return dataBase; } }
  14.  
  15.         internal void Add(GeometryClass key, Object product)
  16.         {
  17.             if (dataBase.ContainsKey(key)) { return dataBase[key]; }
  18.             else { dataBase.Add(key, product); }
  19.         }
  20.         internal Boolean Remove(GeometryClass key)
  21.         {
  22.             if (key != null || dataBase.ContainsKey(key)) { dataBase.Remove(key); return true; }
  23.             else { return false; }
  24.         }
  25.  
  26.         protected DataBaseConcreteProducts() //защищённый конструктор
  27.         {
  28.             dataBase = new Dictionary<GeometryClass , Object >();
  29.         }
  30.     }
« Последнее редактирование: 27-12-2017, 16:15:30 от Александр Ривилис »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Оффтопик. Изучаем C#
« Ответ #158 : 27-12-2017, 16:15:06 »
Мурена
Про правильное форматирование у нас на форуме смотрите у меня в подписи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Мурена

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 0
Re: Оффтопик. Изучаем C#
« Ответ #159 : 27-12-2017, 16:17:09 »
Александр Ривилис,
Да, спасибо!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Оффтопик. Изучаем C#
« Ответ #160 : 27-12-2017, 16:18:51 »
Вот тут совершенно неправильно:
Код - C# [Выбрать]
  1. internal void Add(GeometryClass key, Object product)
  2.         {
  3.             if (dataBase.ContainsKey(key)) { return dataBase[key]; }
  4.             else { dataBase.Add(key, product); }
  5.         }
Разберитесь в типе возвращаемого значения.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Мурена

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 0
Re: Оффтопик. Изучаем C#
« Ответ #161 : 27-12-2017, 16:25:15 »
Да, вижу, вот думаю, что надо изменить, чтобы два раза не выполнялась проверка ключа, а тип возвращаемого значения тоже обдумывается. Вроде не особо хорошо писать у Add какой то тип возвращаемого параметра, может поменять название метода на что то типа GetObject, но вроде возвращать ссылку на то, что посылаю как параметр тоже не особо.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Оффтопик. Изучаем C#
« Ответ #162 : 27-12-2017, 16:29:19 »
что надо изменить, чтобы два раза не выполнялась проверка ключа
Не обращайте внимания. В крайнем случае используйте SortedDictionary<> вместо Dictionary<>
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Оффтопик. Изучаем C#
« Ответ #163 : 27-12-2017, 16:37:35 »
Есть еще метод TryGetValue:   
Код - C# [Выбрать]
  1. internal Object GetOrAdd(GeometryClass key, Object product)
  2. {
  3.        object val = null;
  4.        if (dataBase.TryGetValue(key, out val)) {
  5.           return val;
  6.       } else {
  7.           return (dataBase[key] = product);
  8.       }
  9. }
Код не проверял, но идея должна быть понятна.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Мурена

  • ADN OPEN
  • **
  • Сообщений: 53
  • Карма: 0
Re: Оффтопик. Изучаем C#
« Ответ #164 : 28-12-2017, 00:35:52 »
Александр Ривилис,
Спасибо, немного видоизменила, это то, что нужно