Toán tử tạo danh sách trong LINQ

Các toán tử tạo danh sách trong LINQ bao gồm: DefaultIfEmpty, Empty, Range và Repeat.

Các phương thức Empty, Range và Repeat không phải là phương thức mở rộng cho IEnumerable hoặc IQueryable. Chúng chỉ đơn giản là các phương thức tĩnh được định nghĩa trong lớp tĩnh Enumerable.

Phương thức Mô tả
DefaultIfEmpty Trả về một danh sách mới với giá trị mặc định nếu danh sách đã cho rỗng.
Empty Trả về một danh sách rỗng.
Range Trả về một danh sách kiểu IEnumerable<int> có số lượng phần tử được chỉ định với các giá trị tăng dần bắt đầu từ phần tử đầu tiên.
Repeat Trả về một danh sách kiểu IEnumerable<T> với số lượng phần tử được chỉ định và mỗi phần tử chứa cùng một giá trị được chỉ định.

Toán tử tạo danh sách là một trong những toán tử truy vấn chuẩn của LINQ.

Toán tử truy vấn chuẩn của LINQ | Comdy
Các toán tử truy vấn chuẩn trong LINQ là các phương thức mở rộng cho các kiểu IEnumerable<T> và IQueryable<T>.

Phương thức DefaultIfEmpty trong LINQ

Phương thức mở rộng DefaultIfEmpty trả về một danh sách mới với giá trị mặc định nếu danh sách đã cho rỗng.

Phương thức DefaultIfEmpty có hai phương thức quá tải. Phương thức quá tải đầu tiên không có tham số, nó trả về danh sách mới với giá trị mặc định của kiểu dữ liệu của danh sách.

Phương thức quá tải thứ hai của DefaultIfEmpty nhận tham số là giá trị mặc định sẽ được sử dụng để tạo danh sách mới khi danh sách rỗng.

Ví dụ sau minh họa phương thức DefaultIfEmpty trong LINQ:

IList<string> emptyList = new List<string>();

var newList1 = emptyList.DefaultIfEmpty(); 
var newList2 = emptyList.DefaultIfEmpty("None"); 

Console.WriteLine("Count: {0}" , newList1.Count());
Console.WriteLine("Value: {0}" , newList1.ElementAt(0));

Console.WriteLine("Count: {0}" , newList2.Count());
Console.WriteLine("Value: {0}" , newList2.ElementAt(0));

Đây là kết quả khi biên dịch và thực thi chương trình:

Count: 1
Value: 
Count: 1
Value: None

Trong ví dụ trên, phương thức emptyList.DefaultIfEmpty() trả về một danh sách kiểu string mới có một phần tử có giá trị là null vì null là giá trị mặc định của string.

Trong khi đó phương thức emptyList.DefaultIfEmpty("None") trả về một danh sách kiểu string có một phần tử có giá trị là "None".

Ví dụ sau đây minh họa sử dụng phương thức DefaultIfEmpty trên danh sách kiểu int.

IList<int> emptyList = new List<int>();

var newList1 = emptyList.DefaultIfEmpty(); 
var newList2 = emptyList.DefaultIfEmpty(100);

Console.WriteLine("Count: {0}" , newList1.Count());
Console.WriteLine("Value: {0}" , newList1.ElementAt(0));

Console.WriteLine("Count: {0}" , newList2.Count());
Console.WriteLine("Value: {0}" , newList2.ElementAt(0));

Đây là kết quả khi biên dịch và thực thi chương trình:

Count: 1
Value: 0
Count: 1
Value: 100

Ví dụ sau đây minh họa phương thức DefaultIfEmpty trên danh sách có kiểu dữ liệu phức tạp.

IList<Student> emptyStudentList = new List<Student>();

var newStudentList1 = studentList.DefaultIfEmpty(new Student());
                 
var newStudentList2 = studentList.DefaultIfEmpty(new Student()
{ 
    StudentID = 1, 
    StudentName = "Default" 
});

Console.WriteLine("Count: {0} ", newStudentList1.Count());
Console.WriteLine("Student ID: {0} ", newStudentList1.ElementAt(0));

Console.WriteLine("Count: {0} ", newStudentList2.Count());
Console.WriteLine("Student ID: {0} ", newStudentList2.ElementAt(0).StudentID);

Đây là kết quả khi biên dịch và thực thi chương trình:

Count: 1 
Student ID:  
Count: 1 
Student ID: 1
Lưu ý: Phương thức DefaultIfEmpty không hỗ trợ  cú pháp truy vấn trong LINQ.

Phương thức Empty trong LINQ

Phương thức Empty không phải là phương thức mở rộng của IEnumerable hoặc IQueryable như các phương thức LINQ khác. Nó là một phương thức tĩnh được định nghĩa trong lớp tĩnh Enumerable.

Vì vậy, bạn có thể gọi nó theo cách tương tự như các phương thức tĩnh khác như sau Enumerable.Empty<TResult>().

Phương thức Empty trả về một danh sách rỗng của kiểu IEnumerable<T> như dưới đây.

var emptyCollection1 = Enumerable.Empty<string>();
var emptyCollection2 = Enumerable.Empty<Student>();

Console.WriteLine("Count: {0}", emptyCollection1.Count());
Console.WriteLine("Type: {0}", emptyCollection1.GetType().Name );

Console.WriteLine("Count: {0}", emptyCollection2.Count());
Console.WriteLine("Type: {0}", emptyCollection2.GetType().Name );

Đây là kết quả khi biên dịch và thực thi chương trình:

Count: 0
Type: String[]
Count: 0
Type: Student[]

Phương thức Range trong LINQ

Tương tự phương thức Empty, phương thức Range cũng không phải là phương thức mở rộng của IEnumerable hoặc IQueryable như các phương thức LINQ khác.

Phương thức Range trả về một danh sách kiểu IEnumerable<int> có số lượng phần tử được chỉ định với các giá trị tăng dần bắt đầu từ phần tử đầu tiên.

Ví dụ dưới đây minh họa phương thức Range trong LINQ:

var intCollection = Enumerable.Range(10, 5);
Console.WriteLine("Total Count: {0} ", intCollection.Count());

for(int i = 0; i < intCollection.Count(); i++)
{
    Console.WriteLine("Value at index {0} : {1}", i, intCollection.ElementAt(i));
}

Đây là kết quả khi biên dịch và thực thi chương trình:

Total Count: 5
Value at index 0 : 10
Value at index 1 : 11
Value at index 2 : 12
Value at index 3 : 13
Value at index 4 : 14

Trong ví dụ trên, phương thức Enumerable.Range(10, 5) tạo danh sách kiểu int với 5 phần tử có các giá trị tuần tự bắt đầu từ 10.

Tham số đầu tiên chỉ định giá trị bắt đầu của các phần tử và tham số thứ hai chỉ định số lượng phần tử cần tạo.

Phương thức Repeat trong LINQ

Tương tự phương thức Empty và Range, phương thức Repeat cũng không phải là phương thức mở rộng của IEnumerable hoặc IQueryable như các phương thức LINQ khác.

Phương thức Repeat trả về một danh sách kiểu IEnumerable<T> có số lượng phần tử được chỉ định và mỗi phần tử chứa cùng một giá trị được chỉ định.

Ví dụ dưới đây minh họa phương thức Repeat trong LINQ:

var intCollection = Enumerable.Repeat<int>(10, 5);
Console.WriteLine("Total Count: {0} ", intCollection.Count());

for(int i = 0; i < intCollection.Count(); i++)
{
    Console.WriteLine("Value at index {0} : {1}", i, intCollection.ElementAt(i));
}

Đây là kết quả khi biên dịch và thực thi chương trình:

Total Count: 5
Value at index 0: 10
Value at index 1: 10
Value at index 2: 10
Value at index 3: 10
Value at index 4: 10

Trong ví dụ trên, phương thức Enumerable.Repeat<int>(10, 5) tạo danh sách kiểu int với 5 phần tử có giá trị là 10.

Tham số thứ nhất chỉ định giá trị của tất cả các phần tử và tham số thứ hai chỉ định số lượng phần tử cần tạo.

LINQ
Bài Viết Liên Quan:
Truy vấn LINQ phức tạp
Trung Nguyen 23/04/2020
Truy vấn LINQ phức tạp

Bạn sẽ tìm hiểu một số truy vấn LINQ phức tạp trong hướng dẫn này.

Từ khóa let, into trong LINQ
Trung Nguyen 23/04/2020
Từ khóa let, into trong LINQ

Từ khóa let, into trong LINQ có tác dụng gì? Hướng dẫn khai báo và sử dụng từ khóa let, into trong LINQ.

Thực thi truy vấn LINQ
Trung Nguyen 23/04/2020
Thực thi truy vấn LINQ

Trì hoãn thực thi truy vấn LINQ là gì? Thực thi ngay lập tức truy vấn LINQ là gì? Làm sao để thực thi truy vấn LINQ.

Expression trong LINQ
Trung Nguyen 23/04/2020
Expression trong LINQ

Expression trong LINQ là gì? Cây biểu thức trong LINQ là gì? Cách khai báo và sử dụng chúng trong LINQ.