Bài đăng nổi bật


Phương thức và Nạp chồng phương thức

Các phương thức là một khái niệm cơ bản trong chương trình C# và thực sự là cơ bản cho lập trình hướng đối tượng vì chúng cho phép chúng ta gói gọn hành vi và chức năng trong các đối tượng mà chúng ta tạo trong mã của mình. Bạn sẽ tìm hiểu thêm về lập trình hướng đối tượng trong khóa tiếp theo của loạt bài này vì vậy đừng lo lắng quá nhiều về nó bây giờ.

Chúng tôi sẽ giới thiệu cho bạn cách tạo phương thức của riêng bạn bằng C# và chúng tôi cũng sẽ xem cách gọi các phương thức đó, truyền thông tin mà phương thức cần để thực hiện các chức năng của nó
và sau đó chúng tôi cũng sẽ chỉ cho bạn Làm thế nào để trả về dữ liệu từ các phương thức đó.

Trong nửa sau của mô-đun này, chúng ta sẽ xem xét xử lý ngoại lệ. Mã của bạn càng phức tạp hơn, càng có nhiều tiềm năng cho người dùng tạo ra các ngoại lệ hoặc lỗi trong ứng dụng của bạn, đôi khi chỉ bằng cách sử dụng đơn giản.
Khai báo Phương thức
Khai báo Phương thức
Khả năng định nghĩa và gọi các phương thức là một thành phần cơ bản của lập trình hướng đối tượng, bởi vì các phương thức cho phép bạn đóng gói các hoạt động bảo vệ dữ liệu được lưu trữ bên trong một loại.
Thông thường, bất kỳ ứng dụng nào bạn phát triển bằng cách sử dụng Microsoft.NET Framework và Visual C# sẽ có nhiều phương thức, mỗi phương thức có một mục đích cụ thể. Một số phương thức là cơ bản cho hoạt động của một ứng dụng. Ví dụ: tất cả các ứng dụng máy tính để bàn Visual C# phải có một phương thức gọi là Main xác định điểm vào cho ứng dụng. Khi người dùng chạy ứng dụng Visual C#, common language runtime (CLR) sẽ thực thi phương thức Main cho ứng dụng đó.
Các phương thức có thể được thiết kế để sử dụng nội bộ theo một loại và như vậy được ẩn khỏi các loại khác. Các phương thức public (công khai) có thể được thiết kế để cho phép các loại khác yêu cầu một đối tượng thực hiện một hành động và được đưa ra bên ngoài loại đó.
Bản thân .NET Framework được xây dựng từ các lớp hiển thị các phương thức mà bạn có thể gọi từ các ứng dụng của mình để tương tác với người dùng và máy tính.
Khai báo Phương thức
Một phương thức được khai báo bằng chữ ký phương thức (method signature) và thân phương thức (method body). Phần chữ ký chịu trách nhiệm cung cấp công cụ sửa đổi truy cập (access modifier), kiểu trả về phương thức, tên phương thức và danh sách các tham số. Phần thân chứa phần thực hiện cho những gì phương thức dự định làm. Mỗi thành phần chữ ký phương thức được giải thích ở đây:
  • Access modifier (Công cụ sửa đổi truy cập) - cái này được sử dụng để kiểm soát khả năng truy cập của phương thức (từ đó có thể được gọi)
    • private (riêng tư) - hạn chế nhất và chỉ cho phép truy cập vào phương thức từ trong lớp chứa hoặc struct
    • public (công khai) - ít hạn chế nhất, cho phép truy cập từ bất kỳ mã nào trong ứng dụng
    • protected (được bảo vệ) - cho phép truy cập từ bên trong lớp chứa hoặc từ bên trong các lớp dẫn xuất
    • internal (nội bộ) - có thể truy cập từ các tệp trong cùng một assembly
    • static - chỉ ra phương thức là một thành viên tĩnh của lớp chứ không phải là thành viên của một thể hiện của một đối tượng cụ thể
  • Return type (Kiểu trả về) - được sử dụng để chỉ ra loại dữ liệu mà phương thức sẽ trả về. Sử dụng void nếu phương thức sẽ không trả về giá trị hoặc bất kỳ loại dữ liệu được hỗ trợ nào
  • Method name (Tên phương thức) - tất cả các phương thức cần một tên để bạn biết phải gọi mã nào. Quy tắc định danh cũng áp dụng cho tên phương thức
  • Parameter list (Danh sách tham số) - danh sách tham số được phân tách bằng dấu phẩy để chấp nhận đối số được truyền vào phương thức
Ví dụ method (phương thức):
public Boolean StartService(string serviceName)
{
   // code to start the service
}
Trong ví dụ trên, public là access modifier, Boolean là kiểu trả về, StartService là tên phương thức và chuỗi serviceName là danh sách tham số. Lưu ý rằng danh sách tham số chỉ định loại dữ liệu và tên cho tham số.
Để biết thêm thông tin, bạn có thể xem: Microsoft.Khung NET 4.5: https://aka.ms/edx-dev204x-net01
Gọi Phương thức
Gọi một phương thức
Bạn gọi một phương thức để chạy mã trong phương thức đó từ một phần của ứng dụng của bạn. Bạn không cần phải hiểu cách mã trong một phương thức hoạt động. Bạn thậm chí có thể không có quyền truy cập vào mã, nếu nó nằm trong một lớp trong một assembly mà bạn không có nguồn, chẳng hạn như thư viện lớp .NET Framework.
Để gọi một phương thức, bạn chỉ định tên phương thức và cung cấp bất kỳ đối số tương ứng với các tham số phương thức trong ngoặc đơn.
Đoạn code sau minh hoạ cho cách gọi phương thức StartService, truyền các biến int và Boolean để đáp ứng các yêu cầu tham số cho chữ ký của phương thức.
int upTime = 2000;
bool shutdownAutomatically = true;
StartService(upTime, shutdownAutomatically);  
     
// StartService method.
void StartService(int upTime, bool shutdownAutomatically)
{
   // Perform some processing here.
}


Trả về dữ liệu từ phương thức


Trả về dữ liệu từ phương thức
Nếu phương thức trả về một giá trị, bạn chỉ định cách xử lý giá trị này, thông thường bằng cách gán nó cho một biến cùng loại, trong mã gọi của bạn.
Ví dụ mã sau đây cho thấy cách nắm bắt giá trị trả về của phương thức GetServiceName trong một biến có tên là serviceName.
string serviceName = GetServiceName(); chuỗi GetServiceName() {return "FourthCoffee.SalesService"; }
Ví dụ trên cho thấy trả về một giá trị duy nhất từ phương thức, trong trường hợp này là giá trị chuỗi "FourthCoffee.SalesService". Giá trị chuỗi này được gán cho biến serviceName sau khi gọi phương thức.
Có thể đôi khi bạn muốn trả về nhiều giá trị từ một phương thức. Có ba cách tiếp cận mà bạn có thể thực hiện để thực hiện điều này:
  • Trả về một mảng hoặc bộ sưu tập
  • Sử dụng từ khóa ref
  • Sử dụng từ khóa out
Trong đoạn code ví dụ đầu tiên này, có phần gọi đến phương thức ReturnMultiOut được thực hiện. Các tham số cho phương thức này sử dụng từ khoá out để chỉ ra rằng các giá trị sẽ được trả về cho các tham số này. Lưu ý rằng chúng ta không phải gọi phương thức này bằng câu lệnh gán như trong lệnh gọi phương thức trước đó tới GetServiceName()
ReturnMultiOut(out first, out sValue);
Console.WriteLine($"{first.ToString}, {sValue}");

static void ReturnMultiOut(out int i, out string s)
{
    i = 25;
    s = "using out";
}
Trong ví dụ mã mới này, từ khóa ref được sử dụng để trả về nhiều giá trị từ phương thức. Điển hình là các từ khoá ref yêu cầu các biến đang được sử dụng được khởi tạo trước.
// Using ref requires that the variables be initialized first
string sValue = "";
int first = 0;
ReturnMultiRef(ref first, ref sValue);
Console.WriteLine($"{first.ToString()}, {sValue}");

 void ReturnMultiRef(ref int i, ref string s)
 {
        i = 50;
        s = "using ref";
 }

Method Overloading - Nạp Chồng Phương Thức
Method Overloading - Nạp chồng phương thức
Khi bạn xác định một phương thức, bạn có thể nhận ra rằng nó yêu cầu các bộ thông tin khác nhau trong các trường hợp khác nhau. Bạn có thể định nghĩa các phương thức nạp chồng để tạo nhiều phương thức có cùng chức năng chấp nhận các tham số khác nhau tùy thuộc vào ngữ cảnh mà chúng được gọi.
Các phương thức nạp chồng có cùng tên với nhau để nhấn mạnh mục đích chung của chúng. Tuy nhiên, mỗi phương thức bị nạp chồng phải có một chữ ký duy nhất, để phân biệt nó với các phiên bản nạp chồng khác của phương thức trong lớp.
Chữ ký của một phương thức bao gồm tên và danh sách tham số của nó. Kiểu dữ liệu trả về không phải là một phần của chữ ký. Do đó, bạn không thể xác định các phương thức nạp chồng chỉ khác nhau trong kiểu trả về của chúng. Bạn cũng không thể định nghĩa các phương thức nạp chồng khác nhau trong Chức vụ của các tham số.
Ví dụ mã sau đây cho thấy ba phiên bản của phương thức StopService, tất cả đều có chữ ký duy nhất.
void StopService()
{
   // This method accepts no arguments
}

void StopService(string serviceName)
{
   // This method overload accepts a single string argument
}

void StopService(int serviceId)
{
   // This method overload accepts a single integer argument
}
Khi bạn gọi phương thức StopService, bạn có thể lựa chọn trong các phiên bản nạp chồng bạn sử dụng. Bạn chỉ cần cung cấp các đối số có liên quan để đáp ứng một trường hợp nạp chồng cụ thể, và sau đó trình biên dịch sẽ tìm ra phiên bản nào để gọi dựa trên các đối số mà bạn đã truyền.
Như đã lưu ý ở trên, bạn không thể tạo một phương thức nạp chồng bằng cách chỉ sử dụng vị trí của các đối số cũng như kiểu trả về. Đoạn mã dưới đây cho thấy một ví dụ về các nỗ lực không chính xác trong các phương thức nạp chồng.
void StopService(string serviceName, int seconds)
{
   // This method overload accepts a string argument
   // and an integer argument
}

void StopService(int seconds, string serviceName)
{
   // This method overload accepts an integer argument
   // and a string argument.  It appears different than
   // the preceding method because the arguments are 
   // passed in differently, however, it is still not
   // a valid overload
}

bool StopService(string serviceName, int seconds)
{
   // This method overload accepts a string argument
   // and an integer argument but returns a boolean
   // result.  The difference between this method and
   // the others is the return type.  This is still not
   // a valid overload based on overloading rules.
}

Optional and Named Parameters
Tham số tùy chọn và được đặt tên

Sử dụng tham số tùy chọn và được đặt tên
Một tính năng chính của Visual C# là khả năng tương tác với các ứng dụng và thành phần được viết bằng cách sử dụng các công nghệ khác. Một trong những công nghệ chính mà Windows sử dụng là Mô hình Đối tượng Thành phần - Component Object Model (COM). COM không hỗ trợ nạp chồng phương thức, nhưng thay vào đó sử dụng các phương thức có thể lấy tham số tùy chọn. Để dễ dàng kết hợp các thư viện và thành phần COM vào giải pháp Visual C#, Visual C# cũng hỗ trợ các tham số tùy chọn.
Tham số tùy chọn
Các tham số tùy chọn cũng hữu ích trong các tình huống khác. Chúng cung cấp một giải pháp nhỏ gọn và đơn giản khi không thể sử dụng nạp chồng vì các loại tham số không đủ khác nhau để cho phép trình biên dịch phân biệt giữa các cài đặt. Khi xác định các phương thức sẽ sử dụng các tham số tùy chọn, điều quan trọng cần lưu ý là trước tiên bạn phải chỉ định tất cả các tham số không phải là tùy chọn, sau đó liệt kê các tham số tùy chọn.
Ví dụ mã sau đây cho thấy cách xác định một phương thức chấp nhận một tham số bắt buộc (forceStop) và hai tham số tùy chọn (serviceName, serviceID). Lưu ý rằng cơ chế được sử dụng để biểu thị một tham số tùy chọn là bao gồm một giá trị mặc định.
void StopService(bool forceStop, string serviceName = null, int serviceId =1)
{
   // code here that will stop the service
}
Bạn có thể gọi một phương thức lấy tham số tùy chọn giống như cách bạn gọi bất kỳ phương thức nào khác. Bạn chỉ định tên phương thức và cung cấp bất kỳ đối số cần thiết. Sự khác biệt với các phương thức lấy tham số tùy chọn là bạn có thể bỏ qua các đối số tương ứng và phương thức sẽ sử dụng giá trị mặc định khi phương thức chạy.
Tham số được đặt tên
Theo truyền thống, khi gọi một phương thức, thứ tự và vị trí của các đối số trong lời gọi phương thức tương ứng theo thứ tự của các tham số trong chữ ký phương thức. Nếu các đối số được sắp xếp sai và các loại không khớp, bạn sẽ nhận được một lỗi biên dịch.
Trong Visual C#, bạn có thể chỉ định các tham số theo tên và do đó cung cấp các đối số theo trình tự khác với tham số được xác định trong chữ ký phương thức. Để sử dụng các đối số được đặt tên, bạn cung cấp tên tham số và giá trị tương ứng được phân tách bằng dấu hai chấm.
Ví dụ mã sau đây cho thấy cách gọi phương thức StopService bằng cách sử dụng các đối số được đặt tên để truyền tham số serviceID.
StopService(true, serviceID: 1);

Khi sử dụng các đối số được đặt tên kết hợp với các tham số tùy chọn, bạn có thể dễ dàng bỏ qua các tham số. Bất kỳ tham số tùy chọn nào cũng sẽ nhận được giá trị mặc định của nó. Tuy nhiên, nếu bạn bỏ qua bất kỳ tham số bắt buộc nào, mã của bạn sẽ không thể biên dịch.
Bạn có thể trộn vị trí đối số và tham số được đặt tên. Tuy nhiên, bạn phải chỉ định tất cả các vị trí đối số trước bất kỳ đối số được đặt tên nào.

Post a Comment

أحدث أقدم