Привязать к объектам - выбрать первый объект
Я почти ничего не знаю о 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
3 ответа
@FryHard FirstOrDefault будет работать, но помните, что он возвращает ноль, если ничего не найдено. Этот код не проверен, но должен быть близок к тому, что вы хотите:
var app = Process.GetProcesses().FirstOrDefault(p => p.ProcessName.Contains("MyAppName") && p.MainWindowHandle != IntPtr.Zero);
if (app == null)
return;
SetForegroundWindow(app.MainWindowHandle);
Не использовать Count()
как говорит ICR. Count()
будет перебирать IEnumerable
выяснить, сколько предметов у него есть. В этом случае снижение производительности может быть незначительным, поскольку не так много процессов, но это плохая привычка. Использовать только Count()
когда ваш запрос интересует только количество результатов. Count
почти никогда не бывает хорошей идеей.
Есть несколько проблем с ответом Фрайхарда. Во-первых, из-за отложенного выполнения вы в конечном итоге выполните запрос LINQ дважды, один раз, чтобы получить количество результатов, и один раз, чтобы получить FirstOrDefault
, Во-вторых, нет никаких оснований для использования FirstOrDefault
после проверки счета. Поскольку он может возвращать ноль, вы никогда не должны использовать его без проверки на ноль. Либо сделать apps.First().MainWindowHandle
или же:
var app = apps.FirstOrDefault();
if (app != null)
SetForegroundWindow(app.MainWindowHandle);
Вот почему лучшее решение, без сомнения, от Марка. Это наиболее эффективный и стабильный способ использования LINQ, чтобы получить то, что вы хотите.
Предполагая, что в вашем первом примере приложения является 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 );
}