【问题标题】:Get string[] or process id's from process[] using LINQ使用 LINQ 从进程 [] 获取字符串 [] 或进程 ID
【发布时间】:2011-02-07 18:28:29
【问题描述】:

我已经打开了五个notepad.exe。现在我想知道与每个 notepad.exe 关联的所有进程 ID。

我知道我可以通过以下方式检索记事本进程列表:

Process[] 进程 = Process.GetProcessesByName("notepad");

但现在我想要使用 LINQ 的那些记事本实例的进程 ID 的字符串 []。我怎么做?我知道我可以创建 string[] 并使用 foreach 循环填充 string[] 但我想知道使用 LINQ。

【问题讨论】:

  • 字符串类型的数据是邪恶的。
  • @Snowbear:虽然我大体上同意(我赞成您的评论),但我认为将 PID 作为字符串并没有什么错误(尽管事实上它们已经以整数形式提供给您,并且内存消耗)。即使它们用数字表示,它们也不能用于任何类型的数值计算。它们是标识符,字符串很适合这个角色。
  • @Martinho, Process.GetProcessById(int id) msdn.microsoft.com/en-us/library/76fkb36k.aspx?

标签: c# linq string


【解决方案1】:

你可以写

var ids = Array.ConvertAll(Process.GetProcessesByName("notepad"), p => p.Id);

这将(稍微)比SelectToArray 快,因为它不需要调整数组的大小。

如果您可以使用IEnumerable<int> 而不是数组,Select(没有ToArray)会更快。

【讨论】:

  • hah +1 我知道当我进行相同的编辑时你会发布这个 - 我什至认为 SLaks 会这样做;-)
  • 我不明白“调整数组大小”位。我认为链接SelectToArray 调用不会涉及任何大小调整,因为Select 使用延迟执行并且数组大小是在创建之前计算的。我在这里错了吗?谢谢。
  • @gaearon: ToArray() 无法知道数组应该有多大。 (Select 无法传递原始大小)调整大小发生在 ToArray() 内部。
  • 我刚刚检查了反射器,你是对的。感谢您指出这一点。
【解决方案2】:

您可以使用数组转换而不是 LINQ 进行单行:

int[] processIds = Array.ConvertAll(Process.GetProcessesByName("notepad"), 
                                    p => p.Id);

获取进程ID列表:

Process[] processes = Process.GetProcessesByName("notepad");
var processIdList = processes.Select(p => p.Id).ToList();

要获取数组而不是列表,您可以这样做:

var processIdList = processes.Select(p => p.Id).ToArray();

请注意,进程 ID 的类型为 int。如果你想要一个字符串列表,你可以这样做:

var processIdList = processes.Select(p => p.Id.ToString()).ToArray();

【讨论】:

  • 或者,如果您想要string[],请致电ToArray() 而不是ToList()。如果您只想循环遍历 id 一次,则无需调用任何一种方法,因为 Select() 返回一个 IEnumerable。
  • @Joel:正确,我添加了 ToArray() - 这似乎最能反映 OP 的要求
【解决方案3】:

你可以使用:

Process[] processes = Process.GetProcessesByName("notepad");
string[] ids = processes.Select(p => p.Id.ToString()).ToArray();

但是,我质疑将其放入 string[] 类型的必要性。将 Process.Id 值保留为整数可能会更好:

Process[] processes = Process.GetProcessesByName("notepad");
var ids = processes.Select(p => p.Id);
foreach(int processId in ids)
{
   // Do something with each processId
}

【讨论】:

    【解决方案4】:
    var ids = Process
        .GetProcessesByName("notepad")
        .Select(process => process.Id)
        .ToArray();
    

    【讨论】:

      【解决方案5】:

      大多数答案都集中在从Process [] 中创建string []
      但是为什么你需要一个数组呢?

      如果您需要做的只是稍后循环遍历所有项目,那么您实际上不需要为另一个数组分配内存。而是使用Select 返回的IEnumerable<T>

      var ids = Process
          .GetProcessesByName("notepad")
          .Select(process => process.Id); // returns IEnumerable<int>
      
      foreach (var id in ids)
          DoSomethingWith (id);
      

      您可以以相同的方式选择字符串表示,也可以投影ids

      var stringIds = ids.Select (id => id.ToString ()); // returns IEnumerable<string>
      

      【讨论】:

      • (这就是我回答中最后一行的意思)
      • 抱歉重复,我没有注意到你提到它。如果答案与另一个答案相交,我应该删除它吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 2011-07-16
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多