Lambda
Nội dung bài · 6 mục
Lọc sản phẩm đắt hơn 100.000đ, sắp xếp theo giá, tìm món đầu tiên còn hàng: mỗi việc cần truyền một điều kiện vào method. Viết hẳn một method có tên cho mỗi điều kiện thì quá dài. Lambda cho phép viết điều kiện đó ngay tại chỗ.
Khái niệm
➡️ Lambda: một method không tên viết gọn theo dạng tham số => kết quả, dùng để truyền vào method khác hoặc gán vào biến.
📮 Func: kiểu dùng để lưu lambda có trả về, viết là Func<kiểu vào, kiểu ra>.
p => p > 100000 đọc là: "nhận p, trả về p > 100000".
Ví dụ
Func<decimal, decimal> addVat = price => price * 1.1m;
Console.WriteLine(addVat(100m)); // 110.0
List<decimal> prices = new List<decimal>
{
5000m, 150000m, 30000m, 200000m
};
List<decimal> expensive =
prices.FindAll(p => p > 100000);
foreach (decimal p in expensive)
{
Console.WriteLine(p); // 150000, 200000
}Func<decimal, decimal>: nhậndecimal, trả vềdecimal. Kiểu cuối cùng luôn là kiểu trả về.addVat(100m)gọi lambda giống gọi method.prices.FindAll(p => p > 100000)truyền điều kiện vàoFindAll.FindAlltự chạy lambda với từng phần tử và giữ lại phần tử cho kết quảtrue.
Method viết gọn bằng =>
Method chỉ có một biểu thức, dù là giá trị trả về hay lời gọi trong method
void, cũng viết được bằng =>:
decimal Total(decimal price, int quantity) =>
price * quantity;
Console.WriteLine(Total(5000m, 3)); // 15000Viết như vậy tương đương với { return price * quantity; }. Bạn sẽ gặp cách
viết này rất nhiều trong code thực tế.
Thử ngay
Dán vào Program.cs rồi chạy dotnet run:
Func<int, int> twice = x => x * 2;
Func<int, bool> isEven = x => x % 2 == 0;
Console.WriteLine(twice(twice(3)));
Console.WriteLine(isEven(7));Đoán trước khi chạy: twice(twice(3)) ra 6 hay số khác?
Xem kết quả
12
Falsetwice(3) ra 6, rồi twice(6) ra 12. Lambda gọi lồng nhau như method bình
thường.
Lỗi hay gặp
Dùng var cho lambda mà không có kiểu tham số. Compiler không biết x là
kiểu gì.
// SAI — lỗi compile: không suy ra được kiểu của x
var triple = x => x * 3;// ĐÚNG — khai báo rõ kiểu bằng Func
Func<int, int> triple = x => x * 3;Có ngoặc { } mà quên return. Lambda nhiều dòng phải có return như
method.
// SAI — lỗi compile: thiếu return
Func<int, int> discount = x => { x - 1000; };// ĐÚNG
Func<int, int> discount = x => { return x - 1000; };Tóm tắt
- Lambda là method không tên:
tham số => kết quả. - Lưu lambda bằng
Func<vào, ra>, kiểu cuối là kiểu trả về. - Lambda thường được truyền vào method khác làm điều kiện, như
FindAll. - Method một dòng viết gọn được bằng
=>.
Tự kiểm tra
0/3 câuFunc<string, int> f = s => s.Length; Console.WriteLine(f("shop")); In ra gì?
Khai báo nào đúng cho một lambda nhận decimal và trả về bool?
names là List<string>. names.FindAll(n => n.StartsWith("A")) trả về gì?