C# Series 5- Phương thức mở rộng trong C# và ứng dụng trong Linq

Linq Series 5- Phương thức mở rộng trong C# và ứng dụng trong Linq

Chia sẻ kiến thức 15/04/2023

Phương thức mở rộng trong C# và ứng dụng trong Linq

Xin chào các bạn, trong bài trước chúng ta đã tìm hiểu tường tận ví dụ về lambda expression và khám phá chức năng của nó trong Linq . Hôm nay chúng ta tiếp tục tìm hiểu về phương thức mở rộng trong C# – một tính năng nổi bật trong C# 3.0 và ứng dụng của nó trong Linq.

Phương thức mở rộng trong C#

Các phương thức mở rộng (Exstension Method), như tên gợi ý, là các phương thức bổ sung. Các phương thức mở rộng trong C# cho phép bạn đưa vào các phương thức bổ sung mà không cần sửa đổi, dẫn xuất hoặc biên dịch lại class, struct hoặc interface ban đầu. Các phương thức tiện ích mở rộng có thể được thêm vào lớp tùy chỉnh của riêng bạn, các lớp .NET framework hoặc các lớp hoặc interface của bên thứ ba.

Trong ví dụ sau, IsGreaterThan() là một phương thức mở rộng cho kiểu int, phương thức này trả về true nếu giá trị của biến int lớn hơn tham số số nguyên đã cung cấp.

int i = 10;

bool result = i.IsGreaterThan(100); //returns false 

Phương thức IsGreaterThan() không phải là phương thức của kiểu dữ liệu int (cấu trúc Int32). Nó là một phương thức mở rộng được lập trình viên viết cho kiểu dữ liệu int. Phương thức tiện ích mở rộng IsGreaterThan() sẽ khả dụng trong toàn bộ ứng dụng bằng cách bao gồm namespace mà nó đã được xác định.

Các phương thức mở rộng có một ký hiệu đặc biệt trong intellisense của Visual Studio, để bạn có thể dễ dàng phân biệt giữa các phương thức lớp và các phương thức mở rộng.

Bây giờ hãy xem cách viết một phương thức mở rộng.
Một phương thức mở rộng thực sự là một loại phương thức static đặc biệt được định nghĩa trong một lớp static. Để định nghĩa một phương thức mở rộng, trước hết, hãy định nghĩa một lớp static.

Ví dụ: chúng ta đã tạo một lớp IntExtensions trong namespace ExtensionMethods trong ví dụ sau. Lớp IntExtensions sẽ bao gồm tất cả các phương thức mở rộng áp dụng cho kiểu dữ liệu int. (Bạn có thể sử dụng bất kỳ tên nào cho lớp và namespace.)

namespace ExtensionMethods
{
    public static class IntExtensions
    {

    }
}

Bây giờ, hãy xác định một phương thức static là một phương thức mở rộng trong đó tham số đầu tiên của phương thức mở rộng chỉ định loại áp dụng phương thức mở rộng đó. Chúng ta sẽ sử dụng phương thức mở rộng này trên kiểu int. Vì vậy, tham số đầu tiên phải được đặt trước int với modifier this.

Ví dụ, phương thức IsGreaterThan() hoạt động trên int, vì vậy tham số đầu tiên sẽ là, this int i.

namespace ExtensionMethods
{
    public static class IntExtensions
     {
        public static bool IsGreaterThan(this int i, int value)
        {
            return i > value;
        }
    }
}

Giờ đây, bạn có thể import namespace ExtensionMethods ở bất cứ đâu bạn muốn sử dụng phương thức mở rộng này.

using ExtensionMethods;

class Program
{
    static void Main(string[] args)
    {
        int i = 10;

        bool result = i.IsGreaterThan(100); 

        Console.WriteLine(result);
    }
}

Lưu ý:Sự khác biệt duy nhất giữa phương thức static thông thường và phương thức mở rộng là tham số đầu tiên của phương thức mở rộng chỉ định loại mà nó sẽ thực hiện, trước là từ khóa this.

Các điểm cần ghi nhớ

  1. Các phương thức mở rộng là các phương thức tùy chỉnh bổ sung ban đầu không được bao gồm trong lớp.
  2. Các phương thức tiện ích mở rộng có thể được thêm vào các lớp, struct hoặc interface tùy chỉnh, .NET Framework hoặc bên thứ ba.
  3. Tham số đầu tiên của phương thức mở rộng phải thuộc loại mà phương thức mở rộng được áp dụng,phía trước là từ khóa this.
  4. Các phương thức mở rộng có thể được sử dụng ở bất kỳ đâu trong ứng dụng bằng cách import namespace của phương thức mở rộng.

Ví dụ phương thức mở rộng với kiểu string

Viết một phương thức mở rộng cho kiểu dữ liệu string dùng để do số dòng của chuỗi được ngăn cách bởi ký tự xuống dòng (\n) .

Đầu tiên ta xây dựng một static class có tên là StringExtension

public static class StringExtension
    {
        
    }

Sau đó xây dựng static method  GetCountOfLines() có sử dụng tham sốđầu là kiểu dữ liệu string với từ khóa this ở trước để đại diện cho phương thức mở rộng :

public static class StringExtension
    {
        public static int GetCountOfLines(this string input)
        {
            return input.Split("\n").Length;
        }
    }

Sau đó ta có thể sử dụng phương thức mở rộng ở bất kỳ đâu nếu import namespace của static class đó. Nếu chung namespace thì không cần.

  private static void test_1()
        {
            string str = @"My name is Vu Pham Tuan
                        I live in Ninh Binh 
                        Nice to meet you";
            int countOfLine = str.GetCountOfLines();
            Console.WriteLine("Count of line : " + countOfLine);
        }

Lưu ý : Trong ngôn ngữ lập trình C#, ký tự “@” được gọi là “verbatim identifier” và được sử dụng để chỉ ra rằng một chuỗi là một chuỗi thẳng, không cần thêm ký tự escape để đại diện cho ký tự đặc biệt như “\n”, “\t”, “..” v.v.

Trong quá trình sử dụng phương thức GetCountOfLines() ta sẽ thấy phương thức có đánh dấu (extension) trong Visual Studio để phân biệt với phương thức thông thường khác :

Kết quả chạy chương trình :

Ứng dụng của phương thức mở rộng với Linq

Như ta đã biết các phương thức của linq là các phương thức static của 2 lớp Enumerable hoặc Queryable.

Giả sử có một mảng số nguyên 1, 4, 49, 98, 256, 2 và ta muốn tìm và in ra các số là chẵn và lớn hơn 50 như thông thường ta làm như sau:

 private static void test_2()
{
int[] arr = { 1, 4, 49, 98, 256, 2 };
var evenArr = Enumerable.Where(arr, i => i % 2 == 0);
var evenAndLargerThan50Arr = Enumerable.Where(evenArr, evenNumber => evenNumber > 50);
foreach (int i in evenAndLargerThan50Arr) { Console.WriteLine(i); }
}

Xem lại tham số của phương thức Where() Linq :

Như ta thấy thì phương thức Where của Linq nằm trong static class Enumerable và là static method có tham số đầu với từ khóa this ở trước.Vì vậy đây là phương thức mở rộng. 

Nếu xem với VisualStudio khi gọi hàm thì ta có thể thấy từ (extension) nằm kế phương thức :

Ta có thể viết lại hàm trên như sau:

private static void test_3()
{
int[] arr = { 1, 4, 49, 98, 256, 2 };
var evenAndLargerThan50Arr = arr.Where(number => number % 2 == 0).Where(number => number > 50);
foreach (int i in evenAndLargerThan50Arr) { Console.WriteLine(i); }
}

Tổng kết : Ưu điểm của phương thức mở rộng

Phương thức mở rộng (extension method) là một tính năng trong lập trình hướng đối tượng cho phép chúng ta thêm các phương thức mới vào một lớp tồn tại mà không cần phải thêm các phương thức vào lớp đó trực tiếp. Dưới đây là một vài ưu điểm của phương thức mở rộng:

  1. Giảm sự phức tạp của mã nguồn: Bằng cách sử dụng phương thức mở rộng, chúng ta không cần thay đổi mã nguồn của lớp hiện có để thêm các phương thức mới. Điều này có nghĩa là chúng ta có thể giảm sự phức tạp của mã nguồn một cách đáng kể.
  2. Tăng tính tái sử dụng: Bằng cách tạo phương thức mở rộng, chúng ta có thể sử dụng lại các phương thức cho các lớp khác nhau. Điều này giúp tái sử dụng mã nguồn và giảm thời gian và công sức phát triển ứng dụng.
  3. Dễ dàng mở rộng chức năng: Với phương thức mở rộng, chúng ta có thể thêm các chức năng mới cho các lớp hiện có một cách dễ dàng. Điều này có thể là rất hữu ích trong trường hợp chúng ta muốn thêm chức năng mới cho một lớp mà không muốn làm ảnh hưởng đến các lớp khác.\
  4. Tạo phương thức cho kiểu dữ liệu đã tồn tại: Với phương thức mở rộng, chúng ta có thể thêm phương thức cho các kiểu dữ liệu đã tồn tại, bao gồm các kiểu dữ liệu được định nghĩa bởi ngôn ngữ và các kiểu dữ liệu tùy chỉnh. Điều này giúp cho việc làm việc với kiểu dữ liệu trở nên dễ dàng hơn.

Tài liệu tham khảo

  1.    https://www.tutorialsteacher.com/csharp/csharp-extension-method
  2.    https://github.com/vupt172/linq-series/tree/linq-series-5>  

Học viên Phạm Tuấn Vũ

ĐĂNG KÝ TƯ VẤN HỌC LẬP TRÌNH TẠI FUNiX

Bình luận (
0
)

Bài liên quan

  • Tầng 0, tòa nhà FPT, 17 Duy Tân, Q. Cầu Giấy, Hà Nội
  • info@funix.edu.vn
  • 0782313602 (Zalo, Viber)        
Chat Button
Chat với FUNiX GPT ×

yêu cầu gọi lại

error: Content is protected !!