У меня есть код:
var status = ...
var StatusMapping = new Dictionary<AnotherStatus, IList<Status>>
{
{
AnotherStatus,
new List<Status>
{
Status1,
Status2
}
}
}
foreach (var keyValuePair in StatusMapping)
{
if (keyValuePair.Value.Contains(status))
{
return keyValuePair.Key;
}
}
throw Exception();
Я новичок в С#, перешел с Java. В Java это легко сделать так:
return StatusMapping
.entrySet()
.stream()
.filter(e -> e.getValue().contains(status))
.map(Map.Entry::getKey)
.findFirst()
.orElseThrow(() -> new Exception());
Есть ли способ сделать это с помощью LINQ?
Во-первых, если вы делаете это регулярно, вы можете рассмотреть альтернативную структуру данных. Словари на самом деле не предназначены для частого "поиска на основе какого-либо аспекта ценности".
О, это немного проще в С# :)
var key = StatusMapping.First(x => x.Value.Contains(status)).Key;
First()
сгенерирует исключение, если совпадений нет.
Если вы хотите получить значение по умолчанию, вы можете использовать:
var key = StatusMapping.FirstOrDefault(x => x.Value.Contains(status)).Key;
Это приведет к тому, что key
будет значением по умолчанию для AnotherStatus
(или любого типа ключа).
Обратите внимание, что это работает именно так, потому что KeyValuePair<,>
является типом значения, поэтому значение по умолчанию не равно нулю, с ключом по умолчанию. Если бы у вас была последовательность ссылочных типов, вам нужно что-то вроде:
var property = sequence.FirstOrDefault(whatever)?.Property;
... где ?.
является нулевым условным оператором.
var key = StatusMapping.FirstOrDefault(x => x.Value.Contains(status)).Key;
вызывается со статусом, которого нет в списке значений ни для одного ключа в словаре, переменная ключа будет иметь значение по умолчанию для перечисления состояния. Было ли это поведение преднамеренным? (ожидал исключения)
Status
. Да, это намеренно - я уточнил это как «Если вы хотите получить значение по умолчанию вместо этого». Но First()
будет сгенерировано исключение. Таким образом, вы можете заставить его вести себя так, как вы хотите.