C# từ lâu đã hỗ trợ extension methods, cho phép các nhà phát triển thêm phương thức mới vào các kiểu dữ liệu hiện có mà không cần sửa đổi kiểu gốc. Tuy nhiên, khả năng này trước đây chỉ giới hạn ở các instance methods. Với C# 14, ngôn ngữ này giới thiệu extension members, mở rộng đáng kể những gì bạn có thể mở rộng. Giờ đây bạn có thể thêm extension properties và extension static methods vào các kiểu dữ liệu hiện có. Cải tiến này đặc biệt có giá trị đối với các thư viện polyfill, vốn nhằm mục đích backport các API mới hơn cho các phiên bản .NET cũ hơn.
Mục lục
Tại sao Extension Members lại quan trọng đối với Thư viện Polyfill
Các thư viện polyfill giúp nhà phát triển viết mã sử dụng API hiện đại trong khi vẫn hỗ trợ nhiều phiên bản .NET khác nhau. Như tôi đã giải thích trong bài viết trước về polyfill, các thư viện này cung cấp các triển khai của API mới hơn cho các target framework cũ, giảm nhu cầu sử dụng chỉ thị #if trong mã của bạn.
Trước C# 14, các thư viện polyfill chỉ có thể cung cấp instance methods thông qua extension methods. Hạn chế này có nghĩa là các static methods và properties từ các phiên bản .NET mới hơn không thể được polyfill một cách hiệu quả. C# 14 loại bỏ ràng buộc này, cho phép các thư viện polyfill cung cấp trải nghiệm đầy đủ hơn.
Bạn có thể đọc thêm về extension members trong bài viết trước của tôi: Sử dụng C# 14 extensions để đơn giản hóa việc Parsing Enum hoặc trong bài giới thiệu C# 14 – Khám phá extension members.
Ví dụ Thực tế: ArgumentNullException.ThrowIfNull
Một ví dụ hoàn hảo là phương thức static ArgumentNullException.ThrowIfNull, được giới thiệu trong .NET 6. Phương thức này cung cấp một cách ngắn gọn để xác thực rằng một tham số không phải là null:
public void ProcessData(string data)
{
ArgumentNullException.ThrowIfNull(data);
// Xử lý dữ liệu...
}
Trước C# 14, các thư viện polyfill không thể cung cấp ThrowIfNull như một phương thức static trên ArgumentNullException vì extension methods chỉ hoạt động với instance methods. Với extension static methods của C# 14, các thư viện polyfill giờ đây có thể cung cấp chính xác API này, ngay cả khi nhắm mục tiêu các phiên bản .NET cũ hơn. Giờ đây bạn có thể viết mã sử dụng ArgumentNullException.ThrowIfNull bất kể target framework của bạn là gì, cải thiện khả năng đọc và bảo trì mã.
static class PolyfillExtensions
{
extension(ArgumentNullException)
{
public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
{
if (argument is null)
throw new ArgumentNullException(paramName);
}
}
}
Mặc dù bạn có thể tự định nghĩa các extension static methods và properties của riêng mình, nhưng việc sử dụng một thư viện polyfill được bảo trì tốt có thể giúp bạn tiết kiệm thời gian và công sức.
Sử dụng Meziantou.Polyfill với Extension Members
Lưu ý: Đây không phải lần đầu tiên tôi nhắc đến Meziantou.Polyfill! Tôi đã giới thiệu nó lần đầu trong bài viết trước về polyfill. Kể từ đó, thư viện đã phát triển để tận dụng extension members của C# 14 nhằm mang lại trải nghiệm polyfilling tốt hơn nữa.
Gói Meziantou.Polyfill (GitHub) có thể polyfill hơn 350 kiểu dữ liệu, phương thức và thuộc tính. Nó tận dụng extension members của C# 14 để cung cấp trải nghiệm polyfilling toàn diện. Gói này sử dụng source generators để tự động thêm chỉ những polyfill bạn cần dựa trên target framework của bạn.
Để cài đặt gói:
dotnet add package Meziantou.Polyfill
Sau khi cài đặt, bạn có thể sử dụng các API .NET hiện đại như ArgumentNullException.ThrowIfNull ngay cả khi nhắm mục tiêu các framework cũ hơn như .NET Standard 2.0 hoặc .NET Framework:
public class UserService
{
public void CreateUser(string username, string email)
{
// Hoạt động trên .NET Standard 2.0 trở lên nhờ extension static methods
ArgumentNullException.ThrowIfNull(username);
ArgumentNullException.ThrowIfNull(email);
// Logic tạo người dùng...
}
}
Source generator tự động phát hiện target framework, phiên bản C# và các tùy chọn biên dịch của bạn để tạo ra các extension members phù hợp chỉ khi cần thiết và khả thi. Vì vậy, nếu bạn không sử dụng C# 14 trở lên hoặc nếu target framework đã bao gồm API đó, thì sẽ không có polyfill nào được tạo ra.
Kết luận
Extension members của C# 14 đại diện cho một bước tiến hóa đáng kể trong mô hình mở rộng của ngôn ngữ. Bằng cách cho phép extension properties và static methods, tính năng này giúp các thư viện polyfill cung cấp trải nghiệm đầy đủ và liền mạch hơn khi nhắm mục tiêu nhiều phiên bản .NET. Điều này đồng nghĩa với việc ít chỉ thị #if hơn, mã dễ bảo trì hơn và khả năng sử dụng các API hiện đại ngay cả khi hỗ trợ các framework cũ hơn.
Dù bạn đang sử dụng một thư viện polyfill như Meziantou.Polyfill hay tự tạo extension members của riêng mình, tính năng này mở ra những khả năng mới để viết mã sạch hơn, biểu cảm hơn và hoạt động trên nhiều phiên bản .NET.



