12

我对 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
4

3 回答 3

20

@FryHard FirstOrDefault 将起作用,但请记住,如果没有找到它,它会返回 null。此代码未经测试,但应该接近您想要的:

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

if (app == null)
    return;

SetForegroundWindow(app.MainWindowHandle);
于 2008-08-11T04:25:07.333 回答
2

不要像 ICR 所说的那样使用。将遍历以找出它有多少项目。在这种情况下,由于进程不多,性能损失可能可以忽略不计,但这是一个坏习惯。仅在您的查询只对结果数量感兴趣时使用。几乎从来都不是一个好主意。Count()Count()IEnumerableCount() Count

FryHard 的回答存在几个问题。首先,由于延迟执行,您最终将执行两次 LINQ 查询,一次获取结果数,一次获取FirstOrDefault. FirstOrDefault其次,检查计数后没有任何理由使用。因为它可以返回 null,所以你不应该在不检查 null 的情况下使用它。要么做apps.First().MainWindowHandle要么:

var app = apps.FirstOrDefault();

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

这就是为什么最好的解决方案是马克的,毫无疑问。这是使用 LINQ 获得所需内容的最有效和最稳定的方式。

于 2011-11-18T22:54:00.053 回答
0

假设在您的第一个示例应用程序中是一个 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 );
}
于 2008-08-11T04:20:38.260 回答