Trong bài viết trước, chúng ta đã cùng tìm hiểu về phạm vi hoạt động của biến trong C#, nắm được biến toàn cục là gì, biến cục bộ là gì, biết cách truyền tham số vào hàm. Và các bạn cũng đã biết, hàm sử dụng sẽ tạo ra các bản sao của parameter truyền vào trên RAM. Sau đó dùng những bản sao đó để xử lý dữ liệu. Cho nên kết thúc lời gọi hàm giá trị của các parameter sẽ không bị thay đổi. Vậy để thay đổi giá trị của tham số truyền vào hàm sau khi thực thi khối lệnh trong hàm thì phải dùng đến ref và out.
1. REF TRONG C#
Chúng ta hãy cùng xem 2 ví dụ sau
Ví dụ 1:
Ví dụ 1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
int a = 96;
Console.WriteLine("Gia tri cua a la: " +a);
Demo(a);
Console.ReadLine();
}
static void Demo(int a)
{
a += 5;
Console.WriteLine("Gia tri cua a sau khi thay doi la: " +a);
}
}
}
Trong hàm demo, mình khai báo 1 biến a và cho a = a + 5 rồi in ra màn hình. Trong hàm Main thì mình truyền a = 96 vào parameter của hàm Demo. Kết quả sẽ là 96 + 5 = 101.
Giờ chúng ta sẽ xem thêm ví dụ 2, trong ví dụ này, mình sẽ in giá trị của a sau khi gọi hàm demo. Các bạn hãy xem kết quả ra sao nhé. ^^
Ví dụ 2:
class Program
{
static void Main(string[] args)
{
int a = 96;
Console.WriteLine("Gia tri cua a la: " +a);
DemoRef(a);
Console.WriteLine("Gia tri cua a bay gio la: " + a);
Console.ReadLine();
}
static void DemoRef(int a)
{
a += 5;
Console.WriteLine("Gia tri cua a sau khi thay doi la: " +a);
}
}
Ô! ^^ hay chưa kìa, mình đã gọi hàm DemoRef, tăng a lên thành 101 rồi nhưng sao bây giờ giá trị của biến a vẫn là 96. Đó là vì tham số truyền vào hàm DemoRef sẽ được tạo ra bản sao trên RAM rồi dùng để xử lý dữ liệu. Sau khi kết thúc lệnh gọi hàm thì các parameter vẫn giữ nguyên giá trị ban đầu truyền vào.
Để làm cho giá trị của biến a thay đổi sau khi kết thúc lệnh gọi hàm thì phải thêm từ khóa ref.
Để làm cho giá trị của biến a thay đổi sau khi kết thúc lệnh gọi hàm thì phải thêm từ khóa ref.
Ví dụ 3:
class Program
{
static void Main(string[] args)
{
int a = 96;
Console.WriteLine("Gia tri cua a la: " +a);
DemoRef(ref a);
Console.WriteLine("Gia tri cua a bay gio la: " + a);
Console.ReadLine();
}
static void DemoRef(ref int a)
{
a += 5;
Console.WriteLine("Gia tri cua a sau khi thay doi la: " +a);
}
}
Kết quả:
Vậy là sau khi mình thêm ref vào thì giá trị của tham số truyền vào hàm DemoRef đã bị thay đổi sau khi gọi hàm.
Lưu ý:
- Từ khóa ref phải có trước tên parameter của hàm và trước tên biến truyền vào khi gọi hàm sử dụng
- Truyền parameter có từ khóa ref bắt buộc phải là một biến, không thể truyền vào một hằng vì hằng là giá trị không thay đổi
- Có thể có một hoặc nhiều parameter với từ khóa ref trong lệnh khai báo hàm
- Biến truyền vào có từ khóa ref thì phải được khởi tạo giá trị trước khi truyền vào
- Hàm sử dụng sẽ thao tác trực tiếp với vùng nhớ của các parameter trên RAM. Vì vậy nên kết thúc lời gọi hàm thì giá trị các parameter sẽ bị thay đổi
- Từ khóa ref phải có trước tên parameter của hàm và trước tên biến truyền vào khi gọi hàm sử dụng
- Truyền parameter có từ khóa ref bắt buộc phải là một biến, không thể truyền vào một hằng vì hằng là giá trị không thay đổi
- Có thể có một hoặc nhiều parameter với từ khóa ref trong lệnh khai báo hàm
- Biến truyền vào có từ khóa ref thì phải được khởi tạo giá trị trước khi truyền vào
- Hàm sử dụng sẽ thao tác trực tiếp với vùng nhớ của các parameter trên RAM. Vì vậy nên kết thúc lời gọi hàm thì giá trị các parameter sẽ bị thay đổi
2. OUT TRONG C#
Out được sử dụng tương tự như ref nhưng khác ở chỗ là:
- Biến truyền vào parameter có từ khóa out sẽ không cần khởi tạo giá trị trước khi truyền
- Biến truyền vào parameter có từ khóa out sẽ không cần khởi tạo giá trị trước khi truyền
- Parameter phải được khởi tạo giá trị bên trong thân hàm
Ví dụ:
class Program
{
static void Main(string[] args)
{
int a = 96;
Console.WriteLine("Gia tri cua a la: " +a);
DemoOut(out a);
Console.WriteLine("Gia tri cua a bay gio la: " + a);
Console.ReadLine();
}
static void DemoOut(out int a)
{
a = 5;
a += 5;
Console.WriteLine("Gia tri cua a sau khi thay doi la: " +a);
}
}
Kết quả:
Qua ví dụ này bạn sẽ thấy, việc khởi tạo giá trị biến a = 96 trong hàm Main sẽ không có tác dụng gì khi truyền vào parameter của hàm DemoOut. Trong hàm DemoOut, mình sẽ phải khởi tạo giá trị cho parameter, sau đó giá trị này sẽ được dùng để tính toán.
Vậy nên trong ví dụ trên, ta không cần khởi tạo giá trị cho biến a ở hàm Main nữa.
Kết quả:
Qua ví dụ này bạn sẽ thấy, việc khởi tạo giá trị biến a = 96 trong hàm Main sẽ không có tác dụng gì khi truyền vào parameter của hàm DemoOut. Trong hàm DemoOut, mình sẽ phải khởi tạo giá trị cho parameter, sau đó giá trị này sẽ được dùng để tính toán.
Vậy nên trong ví dụ trên, ta không cần khởi tạo giá trị cho biến a ở hàm Main nữa.
class Program { static void Main(string[] args) { int a; //Console.WriteLine("Gia tri cua a la: " +a); DemoOut(out a); Console.WriteLine("Gia tri cua a bay gio la: " + a); Console.ReadLine(); } static void DemoOut(out int value) { value = 5; value += 5; Console.WriteLine("Gia tri cua a sau khi thay doi la: " + value); } }
Kết quả:
Bài viết liên quan
Hàm đệ quy trong C#
enum trong C#
Struct trong C#
Lớp String trong C#
Vòng lặp foreach trong C#
Mảng đa chiều, mảng của mảng trong C#