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
类型的序列names
到IEnumerable
类型的序列的投影。 如果您了解函数式编程,它将扮演map
的角色。
现在,这里有一个值得理解的微妙点; 这几乎肯定是LINQ最重要但容易被误解的方面之一。 这是延迟执行的概念。 当我们说
IEnumerable persons = names.Select(s => new Person(s));
这实际上并不执行投影(即,它还没有创建使用names
的string
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);
然后,您将遍历列表以获取实例