Truyền dữ liệu kiểu tham chiếu trong c là gì

Kiểu giá trị và kiểu tham chiếu là hai nhóm chính phân loại kiểu dữ liệu của C#. Một biến kiểu giá trị thì biến đó sẽ lưu giá trị của đối tượng lưu trữ, khác với kiểu tham chiếu biến chứa địa chỉ trỏ đến nơi lưu đối tượng thực. Kiểu giá trị mặc định trong các phép toán gán, truyền tham số phương thức, kể cả trả về từ hàm - thì giá trị được sao chép.

public static void valuetypeExample[] {

// biến a, kiểu int là kiểu giá trị, nó lưu giá trị 100  
int a = 100;
// kiểu giá trị khi gán, giá trị được copy  
int b = a;  
Console.WriteLine[$"a = {a}, b = {b}"];
// b gán giá trị mới, a không thay đổi - vì chúng không cùng tham  
// chiếu đến 1 đối tượng chung, mà mỗi biến lưu một giá trị  
b = 200;  
Console.WriteLine[$"a = {a}, b = {b}"];
// a = 100, b = 100  
// a = 100, b = 200  
} Khi biến thuộc các kiểu sau, mặc định nó ứng xử là kiểu giá trị:

  • Các kiểu số nguyên như int, class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 0, class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 1 ...
  • Các kiểu số thực như class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 2, class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 3, class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 4
  • Kiểu class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 5, kiểu class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 6
  • Kiểu cấu trúc class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 7
  • Kiểu liệt kê class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 8
  • Kiểu class Stutent {
    public string Name;  
    public Stutent[string name]  
    {  
        this.Name = name;  
    }  
    
    } 9

Kiểu tham chiếu trong C#

Các biến kiểu tham chiếu nó chứa tham chiếu [địa chỉ nhớ] trỏ đến dữ liệu [là đối tượng], với kiểu tham chiếu hai biến, hay nhiều biến có tên khác nhau có thể cùng trỏ đến cùng mội đối tượng, khi đó dùng biến biến nào truy cập, tác động vào đối tượng đều mang lại kết quả như nhau.

Như vậy khi dùng kiểu tham chiếu, truyền dữ liệu trong hàm hay các phép gán thì không phải là copy đối tượng hay giá trí mà chỉ là truyền tham chiếu [địa chỉ nhớ].

Những biển có kiểu sau thì nó là kiểu tham chiếu:

  • Biến kiểu lớp [ Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 0], các lớp thư viện hoặc lớp do bạn định nghĩa
  • Biến kiểu Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 1
  • Biến kiểu Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 2, các giao diện từ thư viện hoặc tự định nghĩa
  • Biến kiểu Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 3
  • Biến kiểu Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 4
  • Biến kiểu Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 5

Ví dụ có lớp

Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 6

class Stutent {

public string Name;  
public Stutent[string name]  
{  
    this.Name = name;  
}  
} Vì là lớp nên biến kiểu

Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 6 trên sẽ là kiểu tham chiếu, ví dụ:

Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B Điều tương tự khi dùng làm tham số của phương thức, hàm. Nó tham chiếu chứ không copy giá trị

Khai báo một phương thức

// Tham số kiểu lớp, nên là tham chiếu static void UpperName[Stutent stutent] {

stutent.Name = stutent.Name.ToUpper[];  
}

Stutent stutent1 = new Stutent["Xuan Thu Lab"]; UpperName[stutent1]; // Phương thức biến đổi tham số student, có nghĩa là

                 // biến đổi biến student1
Console.WriteLine[stutent1.Name]; // XUAN THU LAB

Truyền tham số kiểu giá trị với dạng tham chiếu trong C#

Có hai hình thức truyền tham số cho phương thức khi nó được gọi là tham trị và tham chiếu

  • tham trị là cách thức mặc định khi tham số đó là kiểu giá trị. Có nghĩa là gán tham số bằng một biến, thì giá trị của biến được copy và sử dụng trong phương thức như biến cục bộ, còn bản thân biến bên ngoài không hề ảnh hưởng.
  • tham chiếu là cách thức mặc định khi tham số đó là kiểu tham chiếu, thì bản thân biến ở tham số sẽ được hàm sử dụng trực tiếp [tham chiếu] chứ không tạo ra một biến cục bộ trong hàm, nên nó có tác động trực tiếp đến biến này bên ngoài.

Trong phần này mở rộng thêm, nếu muốn biến kiểu giá trị nhưng được truyền vào phương thức dạng tham chiếu [giống cách thức biến tham chiếu] thì khai báo tham số ở phương thức, cũng như khi gọi cần cho thêm từ khóa

Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 8

Tham số là các đối tượng lớp, mặc định là tham chiếu.

Khai báo

Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 8 ở tham số phương thức, bắt buộc khi gọi phải sử dụng biến làm tham số chứ không được dùng giá trị.

Ví dụ tham chiếu với biến kiểu giá trị:

Sửa lại phương thức trên như sau

public static void ThamSoThamChieu[ref int x] {

x = x * x;  
Console.WriteLine[x];  
}

Khi sử dụng:

int a = 2; ThamSoThamChieu[ref a]; Console.WriteLine[a]; // In ra // 4 // 4

Ta thấy

// Tham số kiểu lớp, nên là tham chiếu static void UpperName[Stutent stutent] {

stutent.Name = stutent.Name.ToUpper[];  
} 0 sử dụng làm tham số cho phương thức, tham số

// Tham số kiểu lớp, nên là tham chiếu static void UpperName[Stutent stutent] {

stutent.Name = stutent.Name.ToUpper[];  
} 1 tham chiếu đến

// Tham số kiểu lớp, nên là tham chiếu static void UpperName[Stutent stutent] {

stutent.Name = stutent.Name.ToUpper[];  
} 0, và khi trong hàm thay đổi x, nghĩa là thay đổi

// Tham số kiểu lớp, nên là tham chiếu static void UpperName[Stutent stutent] {

stutent.Name = stutent.Name.ToUpper[];  
} 0 bên ngoài. [đều in ra 4]

Ngoài ra nếu gọi

// Tham số kiểu lớp, nên là tham chiếu static void UpperName[Stutent stutent] {

stutent.Name = stutent.Name.ToUpper[];  
} 4 thì sẽ lỗi, vì tham chiếu yêu cầu đối số này phải là biến.

Tham chiếu với out

Ngoài dùng từ khóa

Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 8 trong khai báo tham chiếu, bạn cũng có thể thay thế nó bằng từ khóa

// Tham số kiểu lớp, nên là tham chiếu static void UpperName[Stutent stutent] {

stutent.Name = stutent.Name.ToUpper[];  
} 6, điểm khác biệt duy nhất là nếu dùng từ khóa

// Tham số kiểu lớp, nên là tham chiếu static void UpperName[Stutent stutent] {

stutent.Name = stutent.Name.ToUpper[];  
} 6 thì tham số không cần khởi tạo khi truyền cho phương thức, còn dùng

Stutent a = new Stutent["Nguyễn Văn A"]; Console.WriteLine[a.Name]; // Nguyễn Văn A Stutent b; // Khi gán, tham chiếu không sao chép giá trị mà tham chiếu địa chỉ // nên có thể có a là b, b là a, b thay đổi nghĩa là a thay đổi b = a; b.Name = "Nguyễn Văn B"; Console.WriteLine[a.Name]; // Nguyễn Văn B 8 thì biến làm tham số phải khởi tạo.

Chủ Đề