Привязать к объектам - выбрать первый объект

Я почти ничего не знаю о Linq.

Я делаю это:

var apps = from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select app;

Что дает мне все запущенные процессы, которые соответствуют этим критериям.

Но я не знаю, как получить первый. Примеры, которые я могу найти в сети, по-видимому, подразумевают, что я должен сделать это

var matchedApp = (from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select app).First();

что кажется мне несколько уродливым, а также выдает исключение, если нет соответствующих процессов. Есть ли способ лучше?

ОБНОВИТЬ

Я на самом деле пытаюсь найти первый подходящий элемент и вызвать SetForegroundWindowего

Я придумала это решение, которое также кажется мне уродливым и ужасным, но лучше, чем выше. Есть идеи?

var unused = from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select SetForegroundWindow( app.MainWindowHandle ); // side-effects in linq-query is technically bad I guess
11.08.2008 03:54:43
3 ОТВЕТА
РЕШЕНИЕ

@FryHard FirstOrDefault будет работать, но помните, что он возвращает ноль, если ничего не найдено. Этот код не проверен, но должен быть близок к тому, что вы хотите:

var app = Process.GetProcesses().FirstOrDefault(p => p.ProcessName.Contains("MyAppName") && p.MainWindowHandle != IntPtr.Zero);

if (app == null)
    return;

SetForegroundWindow(app.MainWindowHandle);
20
7.02.2016 18:06:50
как поместить это как запрос, а не как метод расширения?
Quintin Par 25.03.2010 10:48:54
@Quintin, для FirstOrDefault нет синтаксиса «ключевого слова» - вы должны использовать метод расширения.
Matt Hamilton 25.03.2010 11:02:45
Ну, вы могли бы использовать, (query).FirstOrDefault()но метод расширения Sentax легче читать IMO
Jim Deville 18.11.2011 23:00:20
Я никогда не понимал, почему так много людей предпочитают использовать синтаксис SQL вместо синтаксиса метода. Просто удивительно. Красота SQL - это его СКОРОСТЬ, а не СИНТАКС! Синтаксически, SQL - самая ужасная вещь, которую я видел в своей жизни. Квинтин, хотя прошло уже почти три года, ПОЖАЛУЙСТА, начните использовать методы расширения, если вы еще этого не сделали.
vbullinger 8.01.2013 21:57:30

Предполагая, что в вашем первом примере приложения является IEnumerable, вы можете использовать свойства .Count и .FirstOrDefault, чтобы получить единственный элемент, который вы хотите передать SetForegroundWindow.

var apps = from app in Process.GetProcesses()
where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
select app;

if (apps.Count > 0)
{
    SetForegroundWindow(apps.FirstOrDefault().MainWindowHandle );
}
0
11.08.2008 04:20:38
как указано в другом месте, это устраняет преимущества linq (отложенное выполнение), а FirstOrDefault является избыточным со счетчиком
Jim Deville 18.11.2011 23:01:50

Как не использовать , Count()как ICR говорит. Count()итерирует, IEnumerableчтобы выяснить, сколько элементов у него есть. В этом случае снижение производительности может быть незначительным, поскольку не так много процессов, но это плохая привычка. Используйте только Count()тогда, когда ваш запрос интересует только количество результатов. Countпочти никогда не бывает хорошей идеей.

Есть несколько проблем с ответом Фрайхарда. Во-первых, из-за задержки выполнения вы в конечном итоге выполните запрос LINQ дважды: один раз, чтобы получить количество результатов, и один раз, чтобы получить FirstOrDefault. Во-вторых, нет никаких причин использовать FirstOrDefaultпосле проверки счета. Поскольку он может возвращать ноль, вы никогда не должны использовать его без проверки на ноль. Либо делай, apps.First().MainWindowHandleлибо:

var app = apps.FirstOrDefault();

if (app != null)
    SetForegroundWindow(app.MainWindowHandle);

Вот почему лучшее решение, без сомнения, от Марка. Это самый эффективный и стабильный способ использования LINQ, чтобы получить то, что вы хотите.

2
7.02.2016 18:06:37