.NET, объединяющая Exists () с First () - PullRequest
0 голосов
/ 03 июня 2018

Прямо сейчас у меня есть следующий код:

List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();

if (objectList.Exists(o => o.MyProperty == "SomeValue"))
{
    objectInstance = objectList.First(o => o.MyProperty == "SomeValue"));
    DoStuff();
}
else if (objectList.Exists(o => o.MyProperty == "SomeOtherValue"))
{
    objectInstance = objectList.First(o => o.MyProperty == "SomeOtherValue"));
    DoStuff();
}

Есть ли какой-нибудь способ избежать первой проверки Exists, а затем присвоения?

Я знаю, чтоВместо этого я могу использовать FirstOrDefault следующим образом:

List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();

objectInstance = objectList.FirstOrDefault(o => o.MyProperty == "SomeValue"));
if (objectInstance != null)
    DoStuff();
else
{
    objectInstance = objectList.FirstOrDefault(o => o.MyProperty == "SomeValue"));
    if (objectInstance != null)
         DoStuff();
}

Но на самом деле это не кажется более эффективным.

Мне бы хотелось иметь поведение, подобноеTryParse ().Я знаю, что мог бы написать свою собственную обертку для этого, что я сделаю, если нет встроенного способа сделать это, но решил, что я просто проверю и посмотрю, прежде чем я это сделаю.По сути, я бы хотел:

List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();

if (objectList.TryFirst(o => o.MyProperty == "SomeValue", out objectInstance))
    DoStuff();
else if (objectList.TryFirst(o => o.MyProperty == "SomeOtherValue", out objectInstance))
    DoStuff();

Ответы [ 4 ]

0 голосов
/ 03 июня 2018

FirstOrDefault является эквивалентом TryParse.Когда у вас есть отдельное существующее и первые проверки, это заставит коллекцию повторяться дважды.Для очень больших списков или IEnumerables, поддерживаемых определенной функцией (например, выдача результатов из SqlDataReader), это может быть очень дорогостоящим.

0 голосов
/ 03 июня 2018

Вы пытаетесь сократить количество строк исходного кода?Хорошо, вы можете сделать что-то подобное (но это немного медленнее из-за сортировки):

var objectInstance = objectList.OrderByDescending(o => o.MyProperty == "SomeValue").ThenByDescending(o => o.MyProperty == "SomeOtherValue").FirstOrDefault();
if (objectInstance.MyProperty == "SomeValue" || objectInstance.MyProperty == "SomeOtherValue")
{
   DoStuff();
}

Если вам нужно найти ТОЧНО ПЕРВЫЙ элемент в последовательности, которая удовлетворяет вашим условиям, вы также можете выбрать индексы до того, каксортировки.

0 голосов
/ 03 июня 2018
var objectInstance = 
    objectList.FirstOrDefault(o => o.MyProperty == "SomeValue")) ??
    objectList.FirstOrDefault(o => o.MyProperty == "SomeOtherValue"));
if (objectInstance != null) DoStuff();
0 голосов
/ 03 июня 2018

Просто создайте поиск по этому свойству с первыми элементами:

var lookup = objectList.GroupBy(x=> x.MyProperty).ToDictionary(x=> x.MyProperty, x=> x.First());

if(lookup.TryGetValue("SomeValue", out objectInstance) || lookup.TryGetValue("SomeOtherValue", out objectInstance))
{
    DoStuff();
}
...