TOC

This article is currently in the process of being translated into Chinese (~90% done).

LINQ:

Data transformations: the Select() method

在本教程的 LINQ 章节里,到目前位置,我们一直使用简单的数据源,比如整数列表、字符串列表或者是包含简单对象类似于User类的列表。我们将继续这样做,因为它在向你展示各种 LINQ 方法的例子时非常使用,但请注意,使用 LINQ时,其数据源也可以是非常复杂的 XML 文档或者是庞大的数据库。

本文中,我们将讨论的是 Select() 方法,它可以从数据源中获取相应的数据并将其转化成其他内容。就像我之前所说的,这一点在更大更加复杂的数据源中明显更加有用。但是无论怎么样,这里我试图向你展示 Select() 方法是如何工作以及你可以用它做什么。和其他情形一样,我们直接来看一个例子:

using System;  
using System.Collections.Generic;  
using System.Linq;  

namespace LinqSelect1  
{  
    class Program  
    {  
static void Main(string[] args)  
{  
    List<User> listOfUsers = new List<User>()  
    {  
new User() { Name = "John Doe", Age = 42 },  
new User() { Name = "Jane Doe", Age = 34 },  
new User() { Name = "Joe Doe", Age = 8 },  
new User() { Name = "Another Doe", Age = 15 },  
    };  

    List<string> names = listOfUsers.Select(user => user.Name).ToList();  

    foreach (string name in names)  
Console.WriteLine(name);  
}  

class User  
{  
    public string Name { get; set; }  
    public int Age { get; set; }  
}  
    }  
}

请注意我是如何获取到对象列表的,在本例中对象为 User 类型,然后使用 Select() 方法将此列表转化成一个新类型的列表。在该例中,我将对象列表转化成字符串列表,该字符串列表包含了所有用户的名字。这点在很多场景下都是非常实用的,比如,你需要以不同的方式查看数据,或者只需要一部分的数据。当然,它也可以反过来工作,你可以从名字列表中轻易地创建一个 User 列表(但你需要之后手动填充他们的年龄数据):

List<User> listOfUsers = new List<User>()
{
    new User() { Name = "John Doe", Age = 42 },
    new User() { Name = "Jane Doe", Age = 34 },
    new User() { Name = "Joe Doe", Age = 8 },
    new User() { Name = "Another Doe", Age = 15 },
};

List<string> names = listOfUsers.Select(user => user.Name).ToList();

List<User> users = names.Select(name => new User { Name = name }).ToList();

foreach (User user in users)
    Console.WriteLine(user.Name);

这里,注意下我是如何使用 Select() 方法来创建新对象。这是一个非常强大的功能,它可以允许你直接对你的数据做任何事情。这个功能的一个常用用途是制作对象的简易版本,比如说以 JSON 或者 XML 返回 Web 服务。设想一下,假如你的 User 类中有大量的属性(比如生日,性别,邮箱,地址,国家等),但是你只需要这些属性中的一部分子集。这点在安全方面是非常有意义的,它可以使得你不需要返回像用户名和密码等常见的用户属性。下面是一个简化的例子,可以想象一个更加复杂的 User 类。

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqSelect2
{
    class Program
    {
static void Main(string[] args)
{
    List<User> listOfUsers = new List<User>()
    {
new User() { Name = "John Doe", Mail = "john@doe.com", Age = 42 },
new User() { Name = "Jane Doe", Mail = "jane@doe.com", Age = 34 },
new User() { Name = "Joe Doe", Mail = "joe@doe.com", Age = 8 },
new User() { Name = "Another Doe", Mail = "another@doe.com", Age = 15 },
    };

    var simpleUsers = listOfUsers.Select(user => new
    {
Name = user.Name,
Age = user.Age
    });
    foreach (var user in simpleUsers)
Console.WriteLine(user.Name);
}

class User
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Mail { get; set; }
}
    }
}

在本例子中,我们使用 Select() 方法来返回匿名类型的列表,该匿名类型仅包含了在数据源上找到的所有属性的子集。之后,我们将这些对象输出到控制台上,但你可以想象我们将他们返回到一个网站或者其他地方。在这些地方上,保证结果简单是非常重要的,且不应该泄露任何像密码这样的机密信息。

如同之前所讨论过的,我在这些例子中大部分使用的是 LINQ 的方法语法,但当然我们也可以把在此例子中执行的操作改成 LINQ 的查询语法。

// Method syntax
var simpleUsers = listOfUsers.Select(user => new
{
    Name = user.Name,
    Age = user.Age
});

// Query syntax
var simpleUsersQ = (from user in listOfUsers
    select new
    {
Name = user.Name,
Age = user.Age
    }).ToList();

foreach (var user in simpleUsersQ)
    Console.WriteLine(user.Name);

我希望这个例子能够让你清楚地了解你喜欢何种语法,但是无论怎么选择,其结果都是一样的。

概括

Select() 方法允许你将数据源的数据转化成新的类型,比如说只选择其中某一个属性或者返回只包含源对象上的部分属性的对象。


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!