This article is currently in the process of being translated into Russian (~98% done).
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(), чтобы преобразовать этот список в список нового типа. В этом примере я превращаю список объектов в список строк, содержащих имена пользователей. Это чрезвычайно практично во многих ситуациях, когда вам нужно, чтобы ваши данные выглядели по-другому, или когда вам нужна только их часть. Конечно, это также работает и наоборот - вы можете легко создать список пользовательских объектов из списка имен (хотя позже вам придется вручную добавить их возраст).:
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. Представьте, что у вас есть класс пользователя с МНОЖЕСТВОМ свойств (День рождения, Пол, Почта, Адрес, Страна и т.д.), Но вы хотите вернуть только ограниченный набор этих свойств - это также может иметь смысл с точки зрения безопасности, чтобы убедиться, что вы не возвращаете общие свойства пользователя например, имя пользователя и пароль. Вот упрощенный пример - просто представьте себе гораздо более сложный пользовательский класс:
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);
Я надеюсь, что это даст вам более четкое представление о том, какой синтаксис вы предпочитаете, но результат, конечно же, тот же!
Summary
Метод Select() позволяет вам преобразовывать и формировать данные из вашего источника данных в новые варианты, например, выбирая только одно свойство или возвращая объекты, которые содержат только подмножество свойств, найденных в исходном объекте.