C#:在给定构造函数参数数组的情况下,是否有LINQ方法来创建对象数组?

举个例子,假设我有一个名字数组,我想通过调用一个带有string name的构造函数来创建一个Person对象数组。

 class Person() { public string Name { get; set; } public Person(string name) { Name = name; } } ... static void Main() { string[] names = {"Peter", "Paul", "Mary"}; Person[] people; /* I could do this but I'm wondering if there's a better way. */ List persons = new List(); foreach(string name in names) { persons.Add(new Person(name)); } people = persons.ToArray(); } 

我已经被困在.Net 2.0世界太久了,我正试图在我目前的停机时间进行现代化改造……

 // names is string[] Person[] people = names.Select(s => new Person(s)).ToArray(); 

说明:

Enumerable.Select是用于投影的LINQ方法。 也就是说,采取一系列Foo并通过一些规则Func将它们投射到Bar s,这些规则会吃掉Foo并吐出Bar s。 从而

 names.Select(s => new Person(s)) 

IEnumerable类型的序列namesIEnumerable类型的序列的投影。 如果您了解函数式编程,它将扮演map的角色。

现在,这里有一个值得理解的微妙点; 这几乎肯定是LINQ最重要但容易被误解的方面之一。 这是延迟执行的概念。 当我们说

 IEnumerable persons = names.Select(s => new Person(s)); 

这实际上并不执行投影(即,它还没有创建使用namesstring s构造的Person实例作为构造函数参数)。 相反,它创建了一些东西来捕获如何将序列names投射到Person序列中的规则。 只有在实际执行该规则(称为迭代器)时才会进行投影。

导致执行此操作的一种方法是使用方法Enumerable.ToArray ,它基本上表示遍历序列并将结果作为数组返回给我。

还有其他方法可以导致执行。 例如

 IEnumerable persons = names.Select(s => new Person(s)); foreach(Person p in persons) { Console.WriteLine(p.Name); } 

要么

 IEnumerable persons = names.Select(s => new Person(s)); Person p = persons.First(); 

它将执行“第一个”投影(即new Person(names[0] ))并将结果分配给p

当然,这甚至没有达到什么目的

 s => new Person(s) 

是。 这是一个lambda表达式,你可以在我对这个LINQ Expression如何工作的回答中得到它们的介绍? 。

我发布此内容,其他人需要一个稍微不同的场景。 这是我的情况,我用Jason的答案来实现目标。

想象一下,你有一个人的姓名和职位的课程,你想要填写该对象:

 public class Employee { private string name; private string jobTitle; public Employee(){} public Employee(string name, string job) { this.name = name; this.jobTitle = job; } // getters + setters... } 

那你就做

 var IQueryable list = from p in context.Persons join j in context.Jobs on p.jobId == j.jobId select new Employee(p.Name, j.Title); 

然后,您将遍历列表以获取实例