Phương thức (Method) trong C#
Cú pháp khai báo một phương thức cơ bản như sau:
+ Access Modifiers cho biết cấp độ được cho phép truy cập đến hàm này, có các mức độ như public private protected internal , , , … Nếu thiếu thành phần này thì mặc định coi là internal Ngoài ra nếu cho vào từ khóa static ở trước Access Modifiers thì phương thức (hàm) đó gọi là PHƯƠNG THỨC TĨNH (truy cập mà không cần tạo đối tượng lớp), thường dùng kèm với Access Modify tên public để tạo ra các hàm chức năng, tiện ích.
+ return type là kiểu trả về của hàm như int double string long, , , , … nếu hàm không có điều kiện trả về thì để từ khóa void.
+ name_method là tên của phương thức mà bạn đặt.
+ parameters là các tham số của hàm nếu có, các tham số khai báo theo kiểu như int thamso1, nhiều tham số thì cách nhau bởi dấu ,.
+ Cuối cùng là phần { }, trong đó chứa các câu lệnh C# mà khi hàm được gọi nó sẽ thi hành theo logic của code từ đầu đến cuối, hoặc khi gặp lệnh return; Khi hàm có kiểu trả về thì trong thân hàm bắt buộc phải có câu lệnh return value; (với value là giá trị, đối tượng, biểu thức có kiểu cùng kiểu trả về với hàm).
Ví dụ: Viết chương trình nhập a và b Sau đó tính tổng hai số a và b.
()
// Các câu lệnh trong phương thức
} static void Main(string[] args)
Nhapso(out a, out b); int tong = Sum(a, b);
} static int Sum(int a, int b)
} static void Nhapso(out int a, out int b)
Console.WriteLine("Nhap 2 so a va b: "); a = Convert.ToInt32(Console.ReadLine()); b = Convert.ToInt32(Console.ReadLine());
Tham số của phương thức trong C#
Truyền kiểu giá trị
Khi truyền một biến thuộc kiểu giá trị cho một phương thức, một bản san của biến này được tạo ra trong stack của phương thức được gọi Tất cả các thao tác mà phương thức thực hiện trên tham số này đều chỉ tác động trên bản sao.
Sau khi kết thúc phương thức, giá trị của biến tham số vẫn giữ nguyên như trước khi truyền vào phương thức Có nghĩa là những thay đổi (nếu có) của biến trong phương thức sẽ không được giữ lại.
Too long to read on your phone? Save to read later on your computer
Ví dụ: Hoán đổi hai tham số a và b và cho biết kết quả trong quá trình hoán đổi? static void Main(string[] args)
Console.WriteLine($"Truoc khi gan: a = {a}, b = {b}"); valuetypeExample(a, b);
Console.WriteLine($"Sau khi gan: a = {a}, b = {b}");
} public static void valuetypeExample(int a, int b)
// biến a, kiểu int là kiểu giá trị, nó lưu giá trị 100, được gán vào biến Gangiatri
// Kiểu giá trị khi gán cho biến b, giá trị được copy a = b; b = Gangiatri;
Console.WriteLine($"Trong luc gan: a = {a}, b = {b}");
// Kết luận: Những gì hoán đổi trong phương thức thực chất đều tác động lên bản sao của a hay b, chứ không phải chính a, b.
// Do vậy, khi kết thúc phương thức, bản sao bị hủy bỏ, còn, a, b không thay đổi gì.
Truyền kiểu tham chiếu, từ khóa ref
Những phương thức chỉ có thể trả về một giá trị, mặc dù giá trị này có thể là một tập hợp các giá trị Nếu chúng ta muốn phương thức trả về nhiều hơn một giá trị thì cách thực hiện là tạo các tham số với hình thức tham chiếu Khi đó trong phương thức ta sẽ xử lý và gán các giá trị mới cho các tham số tham chiếu này, kết quả là sau khi phương thức thực hiện xong ta dùng các tham số truyền vào như là các kết quả trả về.
Từ khóa ref cho phép truyền một biến thuộc kiểu giá trị nhưng có thể lưu thay đổi như khi sử dụng biến thuộc kiểu tham chiếu Khai khai báo phương thức, nếu tham số truyền vào thuộc kiểu giá trị nhưng cần phải giữ lại những thay đổi thực hiện trong thân phương thức, C# cho phép sử dụng từ khóa ref trước khai báo tham số đó.
Ví dụ: Viết chương trình nhập vào tên, năm sinh 1 người bất kỳ Sau đó in lên màn hình các kết quả sau: tên, năm sinh, tuổi hiện tại của họ. static void Main(string[] args)
// Khi dùng ref: biến phải được khởi tạo trước (ten = "", namsinh = 0, tuoi 0)
// Rồi mới truyền cho phương thức. string ten = ""; int namsinh = 0; int tuoihientai 0;
GetUserInfo(ref ten, ref namsinh, ref tuoihientai);
} private static void ShowResult(string ten, int namsinh, int tuoihientai) {
Console.WriteLine("Nam sinh: " + namsinh);
Console.WriteLine("Tuoi hien tai: " + tuoihientai);
} private static void GetUserInfo(ref string ten, ref int namsinh, ref int tuoihientai)
Console.WriteLine("Nhap ten: "); ten = Console.ReadLine();
Console.WriteLine("Nhap nam sinh: "); namsinh = Convert.ToInt32(Console.ReadLine()); tuoihientai = 2022 - namsinh;
Tham số out
Tham số out là gì?
C# cung cấp một tính năng đặc biệt gọi là tham số ra (out parameter): nếu trước một tham số trong định nghĩa phương thức đặt từ khóa out, tham số đó có thể giữ lại giá trị nó có được trong quá trình thực hiện phương thức, và qua đó có thể dùng để chứa kết quả thực hiện của các lệnh trong thân phương thức.
Khai báo phương thức với tham số out
Ví dụ: Viết chương trình nhập họ tên, chỉ số điện kế tháng trước, chỉ số điện kế tháng này của 1 khách hàng thuê điện kế Sau đó in lên màn hình hóa đơn tiền tiện có dang sau:
Chỉ số cũ : < chỉ số cũ >
Chỉ số mới : < chỉ số mới>
Tiêu thụ : < chỉ số mới - chỉ số cũ >
Yêu cầu tiết kiệm điện static void Main(string[] args)
// Khi gọi và khai báo phương thức đều bắt buộc phải có kèm thêo ref hoặc out trước tên biến muốn truyền theo kiểu tham chiếu.
GetUserInfo(out string hoten, out int chisocu, out int chisomoi, out float tieuthu, out float tiendien);
Console.WriteLine("Hoa don tien dien");
ShowResult(hoten, chisocu, chisomoi, tieuthu, tiendien); Console.WriteLine("Yeu cau tiet kiem dien");
} private static void ShowResult(string hoten, int chisocu, int chisomoi, float tieuthu, float tiendien)
Console.WriteLine("Khach hang: " + hoten);
Console.WriteLine("Chi so cu: " + chisocu);
Console.WriteLine("Chi so moi: " + chisomoi);
Console.WriteLine("Tieu thu: " + tieuthu);
Console.WriteLine("Tien dien: " + tiendien);
} private static void GetUserInfo(out string hoten, out int chisocu, out int chisomoi, out float tieuthu, out float tiendien)
Console.WriteLine("Nhap ho ten: "); hoten = Console.ReadLine();
Console.WriteLine("Nhap chi so cu:
"); chisocu = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Nhap chi so moi: "); chisomoi = Convert.ToInt32(Console.ReadLine()); tieuthu = chisomoi - chisocu; tiendien = (float)(tieuthu * 452.45);
Tham số mặc định
Tham số mặc định là loại tham số đã được gán sẵn giá trị mặc định khi định nghĩa phương thức, và do đó khi phương thức có thể bỏ qua việc truyền tham số này. Tham số mặc định không có gì khác biệt với tham số bình thường khi sử dụng trong thân phương thức Tuy nhiên, C# bắt buộc các tham số mặc định phải nằm cuối cùng trong danh sách tham số.
Khi gọi phương thức, nếu không cần truyền giá trị khác với giá trị mặc định, có thể bỏ qua tham số mặc định này.
Ví dụ: Nhập vào họ, lót, tên của bạn.
// tham số mặc định, gọi phương thức theo tên tham số static void Main(string[] args)
} static void ShowInfo(string first, string mid, string last)
Console.WriteLine("First name: " + first); Console.WriteLine("Mid name: " + mid); Console.WriteLine("Last name: " + last);
Nạp chồng phương thức
Nạp chồng phương thức C# là gì?
Nạp chồng phương thức (method overloading) là hiện tượng trong một class có thể tồn tại nhiều phương thức trùng tên.
Mỗi overload này nhận một một danh sách tham số khác nhau Ứng với mỗi overload sẽ cung cấp thông tin chi tiết riêng.
Khi gặp hiện tượng nạp chồng phương thức, trình phiên dịch của C# sẽ căn cứ vào danh sách tham số thực của lời hàm để quyết định xem người lập trình đang muốn gọi phương thức nào.
Vì vậy, các phương thức nạp chồng phải khác nhau về tham số Nói một cách chính xác hơn, các phương thức nạp chồng trong C# bắt buộc phải khác nhau về signature (tên của phương thức; số lượng tham số; kiểu và trật tực các tham số; các từ khóa điều khiển cho tham số (out, ref, in).
Ví dụ: static void Main(string[] args)
// Có nhiều phương thức trùng tên Add.
// Mỗi phương thức có những tham số khác nhau với một thông tin riêng int sum = Add(12, 30); float s2 = Add(12, 12.36f); long s3 = Add(10L, 20, 6); static int Add(int a, int b)
} static float Add(int b, float a)
} static double Add(double a, double b)
} static long Add(long a, long b)
} static long Add(long a, int b, short c)
} static long Add(long a, long b, short c)
Signature của phương thức trong C#
Một ký hiệu (signature) của một phương thức được định nghĩa như tên của phương thức cùng danh sách với tham số của phương thức Hai phương thức khác nhau khi ký hiệu của chúng khác nhau Khác nhau tức là khác nhau khi tên phương thức khác nhau hay danh sách tham số khác nhau Danh số tham số được xem là khác nhau bởi số lượng các tham số hoặc kiểu dữ liệu của tham số.
Ví dụ đoạn mã sau, phương thức thứ nhất khác phương thức thứ hai do số lượng tham số khác nhau Phương thức hai khác phương thức thứ ba do kiểu dữ liệu tham số khác nhau.
Phương thức đệ quy
Đệ quy là phương thức khai báo, trong thân của nó có gọi là chính nó Đệ quy khá giống vòng lặp, cần điều kiện dừng để tránh đệ quy vô tận. Phương thức đệ quy có thể chuyển qua sử dụng vòng lặp.
Ví dụ: Ứng dụng đệ quy để tính giai thừa của n. void myMethod(int a); void myMethod(int a, int b); void myMethod(int a, string b); static void Main(string[] args)
Nhapn(out n); long nGT = GiaiThua(n);
Console.WriteLine($"Vay {n}! = " + nGT); Console.ReadKey();
{ long g = 1; for (int i = 1; i 0 thì kiểm tra xem N có phải là số nguyên tố hay không? static void Main(string[] args)
Console.WriteLine("Vui long nhap N > 0"); int N = Convert.ToInt32(Console.ReadLine()); bool kq = ktraNgTo(N); if (kq)
Console.WriteLine($"{N} la so nguyen to.");
Console.WriteLine($"{N} khong phai so nguyen to.");
Bài 2: Nhập 1 số N nguyên dương, sau đó in ra N số nguyên tố đầu tiên static void Main(string[] args)
Console.WriteLine($"Vay {N} so nguyen to dau tien la: "); hienThiKQ(N);
{ int count = 0; int i = 2; while (count < N)
} for (int i = 2; i 0)
Bài 3: In ra N số hạng đầu tiên của dãy Fibonacci static void Main(string[] args)
Console.WriteLine($"{n} so hang dau tien cua day Fibonacci la: "); hienThiKQ(n);
} static void nhapN(out int n)
Console.WriteLine("Vui long nhap N > 0"); n = Convert.ToInt32(Console.ReadLine());
Bài 4: Nhập vào 1 số nguyên dương N Cho biết tổng các ký tự số của N là bao nhiêu? static void Main(string[] args)
Console.WriteLine($"Tong cac ky tu so cua {N} la {kq}");
{ int sum = 0; int sodu = 0; while (N >
} static void NhapN(out int N)
Console.WriteLine("Vui long nhap N > 0");
Bài 5: Nhập vào 1 số N nguyên dương Cho biết số này có đối xứng không? static void Main(string[] args)
Console.WriteLine("Vui long nhap N > 0"); int N = Convert.ToInt32(Console.ReadLine()); bool kqDX = Doixung(N); if (kqDX)
Console.WriteLine($"{N} la so doi xung.");
Console.WriteLine($"{N} khong phai la so doi xung.");
Bài 6: Nhập vào N số vào mảng a, cho biết mang a có đối xứng hay không? static void Main(string[] args)
{ int[] numbers = nhapMang(); bool Mangdx = Doixung(numbers); if (Mangdx)
Console.WriteLine("Day la mang doi xung.");
Console.WriteLine("Day khong phai la mang doi xung."); }
} static bool Doixung(int[] numbers)
{ bool dx = true; for (int i = 0; i < (numbers.Length + 1) / 2; i++)
{ if (numbers[i] != numbers[numbers.Length - i - 1]) { dx = false;
Console.WriteLine("Vui long nhap so luong phan tu mang N > 0");
} int[] a = new int[N]; for (int i = 0; i < a.Length; i++)
Console.Write($"a[{i}] = "); a[i] = Convert.ToInt32(Console.ReadLine());
Bài 7: Nhập vào các giá trị số vào mảng gồm N phần tử In ra số nhỏ nhất và số lớn nhất trong mảng static void Main(string[] args)
{ int[] numbers = nhapMang(); int MAX GiatriMax(numbers); int MIN GiatriMin(numbers);
Console.WriteLine("Gia tri lon nhat trong mang la: " +
MAX); Console.WriteLine("Gia tri nho nhat trong mang la: "
} static int GiatriMax(int[] numbers)
{ int max = numbers[0]; for (int i = 0; i < numbers.Length; i++)
} static int GiatriMin(int[] numbers)
{ int min = numbers[0]; for (int i = 0; i < numbers.Length; i++)
Console.WriteLine("Vui long nhap so luong phan tu mang N > 0");
} int[] a = new int[N]; for (int i = 0; i < a.Length; i++)
Console.Write($"a[{i}] = "); a[i] = Convert.ToInt32(Console.ReadLine());
Bài 8: Nhập các phân tử của ma trận vuông cấp n, kiểm tra ma trận này có phải là ma trận đối xứng qua đường chéo chính không? static void Main(string[] args)
{ int[,] numbers = nhapMang(); bool kqDX = Doixung(numbers); if (kqDX)
Console.WriteLine("Ma tran doi xung qua duong cheo chinh."); } else
Console.WriteLine("Ma tran khong doi xung qua duong cheo chinh."); }
} static bool Doixung(int[,] numbers)
{ bool dx = true; for (int i = 0; i < numbers.GetLength(0); i++)
Console.WriteLine("Vui long nhap so luong phan tu mang N > 0"); n = Convert.ToInt32(Console.ReadLine());
} int[,] A = new int[n, n]; for (int i = 0; i < n; i++)
Bài 9: Nhập ma trận vuông cấp n Tính tổng các phần tử chẵn nằm ở tam giác dưới đường chéo chính (kể cả đường chéo chính) static void Main(string[] args)
{ int[,] numbers = nhapMang(); int kqtongPTchan = Tinhtong(numbers);
Console.WriteLine("Tong cac phan tu chan nam o tam giac duoi la: " + kqtongPTchan);
} static int Tinhtong(int[,] numbers)
{ int sum = 0; for (int i = 0; i < numbers.GetLength(0); i++)
Console.WriteLine("Vui long nhap so luong phan tu mang N > 0"); n = Convert.ToInt32(Console.ReadLine());
Random r = new Random(); for (int i = 0; i < n; i++)
Bài 10: Sắp xếp các phần tử trong 1 mảng gồm n số nguyên theo thứ tự từ nhỏ đến lớn static void Main(string[] args)
Console.WriteLine("Sap xep theo thu tu tu nho den lon: ");
Array.Sort(numbers); foreach (int number in numbers)
Console.WriteLine("Nhap so luong phan tu mang"); n = Convert.ToInt32(Console.ReadLine()); } int[] A = new int[n];
Random xxx = new Random(); for (int i = 0; i < A.Length; i++)
Bài 11: Liệt kê các số chính phương trong đoạn [a, b] static void Main(string[] args)
Console.WriteLine("Ket qua: "); hienThi(a, b);
} static void hienThi(int a, int b)
} private static bool chinhPhuong(int i)
{ int s = (int)Math.Sqrt(i); return s * s == i;
} static void nhap(out int a, out int b)
Console.WriteLine("Nhap so nguyen a > 0: "); a = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Nhap so nguyen b > a: "); b = Convert.ToInt32(Console.ReadLine());