オブジェクトへのリンク - 最初のオブジェクトを選択
-
08-06-2019 - |
質問
linq についてはほとんど何も知りません。
私はこれをやっています:
var apps = from app in Process.GetProcesses()
where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
select app;
これにより、その基準に一致する実行中のプロセスがすべて取得されます。
しかし、最初の1つを取得する方法がわかりません。ネットで見つけることができる例は、これを行う必要があることを示唆しているようです
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 の回答にはいくつかの問題があります。まず、理由としては、 遅延実行, 、結果の数を取得するために 1 回、結果の数を取得するために 1 回、合計 2 回、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 );
}