Индексатор в Dictionary выдает исключение, если ключ отсутствует. Есть ли реализация IDictionary, которая вместо этого вернет значение по умолчанию (T)?
Я знаю о методе "TryGetValue", но его невозможно использовать с linq.
Будет ли это эффективно делать то, что мне нужно ?:
myDict.FirstOrDefault(a => a.Key == someKeyKalue);
Я не думаю, что это будет, поскольку я думаю, что он будет перебирать ключи вместо использования поиска по хэшу.
c#
.net
hash
dictionary
TheSoftwareJedi
источник
источник
Ответы:
В самом деле, это вообще не будет эффективно.
Вы всегда можете написать метод расширения:
Или с C # 7.1:
Это использует:
источник
return (dictionary.ContainsKey(key)) ? dictionary[key] : default(TValue);
System.Collections.Generic.CollectionExtensions
, поскольку я только что попробовал, и он есть.Использование этих методов расширения может помочь ..
источник
Func<K, V>
.Если кто-то использует .net core 2 и выше (C # 7.X), вводится класс CollectionExtensions, который может использовать метод GetValueOrDefault для получения значения по умолчанию, если ключа нет в словаре.
источник
Collections.Specialized.StringDictionary
обеспечивает неисключительный результат при поиске значения отсутствующего ключа. По умолчанию регистр не учитывается.Предостережения
Он действителен только для его специализированных применений и, будучи разработанным до обобщения, не имеет очень хорошего счетчика, если вам нужно просмотреть всю коллекцию.
источник
Если вы используете .Net Core, вы можете использовать метод CollectionExtensions.GetValueOrDefault . Это то же самое, что и реализация, представленная в принятом ответе.
источник
источник
Можно определить интерфейс для функции поиска по ключу словаря. Я бы, наверное, определил это примерно так:
Версия с неуниверсальными ключами позволит коду, который использует код, использующий неструктурированные типы ключей, допускать произвольную вариацию ключа, что невозможно с параметром универсального типа. Нельзя позволять использовать изменяемый
Dictionary(Of Cat, String)
объект как изменяемый,Dictionary(Of Animal, String)
поскольку последний позволитSomeDictionaryOfCat.Add(FionaTheFish, "Fiona")
. Но нет ничего плохого в использовании изменяемогоDictionary(Of Cat, String)
в качестве неизменяемогоDictionary(Of Animal, String)
, поскольку егоSomeDictionaryOfCat.Contains(FionaTheFish)
следует рассматривать как совершенно правильно сформированное выражение (оно должно возвращатьfalse
без необходимости поиска в словаре все, что не относится к типуCat
).К сожалению, единственный способ действительно использовать такой интерфейс - это обернуть
Dictionary
объект в класс, реализующий интерфейс. Однако в зависимости от того, что вы делаете, такой интерфейс и допускаемая им вариативность могут оправдать ваши усилия.источник
Если вы используете ASP.NET MVC, вы можете использовать класс RouteValueDictionary, который выполняет эту работу.
источник
Этот вопрос помог подтвердить , что
TryGetValue
играетFirstOrDefault
роль.Одна интересная функция C # 7, о которой я хотел бы упомянуть, - это функция выходных переменных , и если вы добавите в уравнение условный оператор null из C # 6, ваш код может быть намного проще без необходимости в дополнительных методах расширения.
Обратной стороной этого является то, что вы не можете делать все так встроенно;
Если нам нужно / мы хотим это сделать, мы должны закодировать один метод расширения, такой как у Джона.
источник
Вот версия @ JonSkeet для мира C # 7.1, которая также позволяет передавать необязательное значение по умолчанию:
Возможно, будет более эффективным иметь две функции для оптимизации случая, когда вы хотите вернуть
default(TV)
:К сожалению, в C # (пока?) Нет оператора запятой (или оператора точки с запятой, предложенного в C # 6), поэтому вам нужно иметь фактическое тело функции (ах!) Для одной из перегрузок.
источник
Я использовал инкапсуляцию для создания IDictionary с поведением, очень похожим на карту STL , для тех из вас, кто знаком с C ++. Для тех, у кого нет:
TL / DR - SafeDictionary написан так, чтобы никогда не вызывать исключения ни при каких обстоятельствах, кроме извращенных сценариев. , таких как памяти (или пожар) компьютера. Для этого он заменяет Add на поведение AddOrUpdate и возвращает значение по умолчанию вместо выдачи NotFoundException из индексатора.
Вот код:
источник
Начиная с .NET core 2.0 вы можете использовать:
источник
Как насчет этого однострочника, который проверяет наличие ключа с помощью,
ContainsKey
а затем возвращает либо обычно полученное значение, либо значение по умолчанию с использованием условного оператора?Нет необходимости реализовывать новый класс Dictionary, который поддерживает значения по умолчанию, просто замените операторы поиска короткой строкой выше.
источник
Это может быть однострочный запрос для проверки
TryGetValue
и возврата значения по умолчанию, если это такfalse
.myKey = "One"
=>value = 1
myKey = "two"
=>value = 100
myKey = "Four"
=>value = 4
Попробуйте онлайн
источник
Нет, потому что в противном случае, как бы вы узнали разницу, когда ключ существует, но хранит нулевое значение? Это могло быть значительным.
источник