개체에 대한 Linq - 첫 번째 개체 선택
-
08-06-2019 - |
문제
나는 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
해결책
@FryHard FirstOrDefault는 작동하지만 아무것도 발견되지 않으면 null을 반환한다는 점을 기억하세요.이 코드는 테스트되지 않았지만 원하는 코드와 유사해야 합니다.
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
거의 좋은 생각이 아닙니다.
FryHard의 답변에는 몇 가지 문제가 있습니다.첫째, 때문에 지연된 실행, LINQ 쿼리를 두 번 실행하게 됩니다. 한 번은 결과 수를 가져오고 한 번은 결과를 가져옵니다. FirstOrDefault
.둘째, 사용할 이유가 전혀 없습니다. FirstOrDefault
개수를 확인한 후.null을 반환할 수 있으므로 null을 확인하지 않고 사용하면 안 됩니다.그러거나 말거나 apps.First().MainWindowHandle
또는:
var app = apps.FirstOrDefault();
if (app != null)
SetForegroundWindow(app.MainWindowHandle);
이것이 바로 최고의 솔루션이 의심의 여지없이 Mark의 솔루션인 이유입니다.이는 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 );
}