举个例子,假设我有一个名字数组,我想Person通过调用一个构造函数来创建一个对象数组string name.
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<Person> persons = new List<Person>();
foreach(string name in names)
{
persons.Add(new Person(name));
}
people = persons.ToArray();
}
Run Code Online (Sandbox Code Playgroud)
我已经被困在.Net 2.0世界太久了,我正试图在我目前的停机时间进行现代化改造......
jas*_*son 57
// names is string[]
Person[] people = names.Select(s => new Person(s)).ToArray();
Run Code Online (Sandbox Code Playgroud)
说明:
Enumerable.Select是用于投影的LINQ方法.也就是说,采取一系列Foos并Bar通过一些Func<Foo, Bar>吃Foos和吐出Bars的规则将它们投射到s.从而
names.Select(s => new Person(s))
Run Code Online (Sandbox Code Playgroud)
是序列的投影names类型的IEnumerable<string>到类型的序列IEnumerable<Person>.如果您了解函数式编程,那么它就起到了作用map.
现在,这里有一个值得理解的微妙点; 这几乎肯定是LINQ中最重要但容易被误解的方面之一.这是延迟执行的概念.当我们说
IEnumerable<Person> persons = names.Select(s => new Person(s));
Run Code Online (Sandbox Code Playgroud)
这实际上并不执行投影(即,它还没有创建Person使用strings in names作为构造函数参数构造的实例).相反,它会创建一些东西来捕获如何将序列投影names到一系列序列中的规则Person.只有在实际执行该规则(称为迭代器)时才会进行投影.
导致执行此操作的一种方法是使用Enumerable.ToArray基本上反复遍历序列的方法,并将结果作为数组返回给我.
还有其他方法可以导致执行.例如
IEnumerable<Person> persons = names.Select(s => new Person(s));
foreach(Person p in persons) {
Console.WriteLine(p.Name);
}
Run Code Online (Sandbox Code Playgroud)
要么
IEnumerable<Person> persons = names.Select(s => new Person(s));
Person p = persons.First();
Run Code Online (Sandbox Code Playgroud)
这将执行"第一"投影(即,new Person(names[0]))并将结果分配给p.
当然,这甚至没有达到什么目的
s => new Person(s)
Run Code Online (Sandbox Code Playgroud)
是.这是一个lambda表达式,你可以在我对这个LINQ Expression如何工作的回答中对它们进行介绍?.