Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Nạp chồng phương thức (Method Overloading) trong C#

Method Overloading cho phép nhiều phương thức cùng tên nhưng khác signature (số lượng, kiểu, thứ tự tham số) trong cùng một class/struct. Đây là dạng Compile-time Polymorphism.

2 cách tạo overload

  1. Khác số lượng tham số
  2. Khác kiểu dữ liệu tham số

KHÔNG tạo overload chỉ khác: kiểu trả về, tên tham số, modifier (ref/out - trừ khi signature khác).

Ví dụ: Khác số lượng tham số

using System;

public class Calculator
{
    public int Mul(int a, int b) => a * b;
    public int Mul(int a, int b, int c) => a * b * c;
    public int Mul(int a, int b, int c, int d) => a * b * c * d;
    
    // C# 4.0+: Optional parameters thay thế overload đơn giản
    public int MulOpt(int a, int b, int c = 1, int d = 1) => a * b * c * d;
}

class Program
{
    static void Main()
    {
        Calculator calc = new Calculator();
        Console.WriteLine($"2 params: {calc.Mul(10, 15)}");       // 150
        Console.WriteLine($"3 params: {calc.Mul(8, 13, 20)}");     // 2080
        Console.WriteLine($"4 params: {calc.Mul(3, 7, 10, 7)}");   // 1470
        
        // Optional params
        Console.WriteLine($"Optional 3: {calc.MulOpt(2, 3, 4)}");  // 24 (d=1)
    }
}

Ví dụ: Khác kiểu dữ liệu

public class Printer
{
    public void Print(int i) => Console.WriteLine($"Int: {i}");
    public void Print(double d) => Console.WriteLine($"Double: {d}");
    public void Print(string s) => Console.WriteLine($"String: {s}");
    public void Print(bool b) => Console.WriteLine($"Bool: {b}");
    public void Print(int[] arr) => Console.WriteLine($"Array: [{string.Join(", ", arr)}]");
}

Overload Resolution (Quy tắc chọn overload)

  1. Exact match (khớp chính xác kiểu).
  2. Implicit conversion (widening: int→long→float→double, derived→base).
  3. Params array (ưu tiên thấp hơn fixed params).
  4. Non-generic > Generic (nếu signature giống nhau).
void Foo(int x) { }
void Foo(double x) { }
void Foo(object x) { }

Foo(5);      // Foo(int) - exact
Foo(5L);     // Foo(long) - exact (nếu có) else Foo(double) - implicit int→long→double
Foo("test"); // Foo(object) - implicit string→object

Best Practices

  • Dùng Optional Parameters (C# 4+) thay vì overload cho tham số tùy chọn: void Foo(int a, int b = 0).
  • Dùng Named Arguments để rõ ràng: Foo(a: 1, c: 3).
  • Tránh overload gây ambiguous: Foo(int) và Foo(double) gọi Foo(5) chọn int.
  • XML Doc cho từng overload: /// .

So sánh Overloading vs Overriding

Đặc điểmOverloading (Nạp chồng)Overriding (Ghi đè)
Mối quan hệCùng classBase ↔ Derived class
SignaturePhải khácPhải giống hệt
BindingStatic (Compile-time)Dynamic (Runtime)
Từ khóaKhông cầnvirtual/override
Mục đíchCùng tên, hành vi khác cho input khácThay đổi hành vi cho cùng input