Trong C#, những cái gì là reference type thì variable đều trỏ lên heap.
Còn value type thì variable thường nằm trên stack.
Khi bạn sử dụng value type làm tham số cho hàm, khi hàm đó chạy là cả 1 cục dữ liệu value type sẽ được bỏ vào hàm.
Còn nếu là reference type làm tham số thì chỉ có cái reference (có thể coi là 1 dạng pointer cao cấp) được bỏ vào hàm thôi, rồi từ reference đó truy cập đến dữ liệu thật.
Theo mình biết thì thường khi gọi hàm, các tham số sẽ được push vào stack, dùng kiểu reference thì tiết kiệm được stack, nhưng tốc độ chạy thì chưa chắc vì làm thế này là dùng heap vốn không nhanh hơn stack, thường thì những dữ liệu loại nhỏ mà được sử dụng liên tục thì có thể dùng stack, quy tắc của Microsoft để lựa chọn class và struct.
À mà bởi vì reference type nó kiểu như con trỏ, nên có thể gán null, value type không như vậy được.
Có 1 ví dụ khá hay trên này nói về việc gán dữ liệu giữa 2 loại: gán biến class thì nó gán reference, gán biến struct thì nó gán cả khối dữ liệu (ngoại trừ trường hợp bạn đi overload operator nhé).
using System;
// PrintedPage is a value type
struct PrintedPage
{
public string Text;
}
// WebPage is a reference type
class WebPage
{
public string Text;
}
class Demonstration
{
static void Main()
{
// First look at value type behaviour
PrintedPage originalPrintedPage = new PrintedPage();
originalPrintedPage.Text = "Original printed text";
// Copy all the information
// ở đây là struct nên sẽ copy cả khối dữ liệu - tất cả các biến trong struct
PrintedPage copyOfPrintedPage = originalPrintedPage;
// Change the new copy
copyOfPrintedPage.Text = "Changed printed text";
// Write out the contents of the original page.
// Output=Original printed text
Console.WriteLine ("originalPrintedPage={0}", originalPrintedPage.Text);
// Now look at reference type behaviour
WebPage originalWebPage = new WebPage();
originalWebPage.Text = "Original web text";
// Copy just the URL
// ở đây là class nên chỉ copy reference
WebPage copyOfWebPage = originalWebPage;
// Change the page via the new copy of the URL
copyOfWebPage.Text = "Changed web text";
// Write out the contents of the page
// Output=Changed web text
Console.WriteLine ("originalWebPage={0}",
originalWebPage.Text);
// Now change the copied URL variable to look at
// a different web page completely
copyOfWebPage = new WebPage();
copyOfWebPage.Text = "Changed web page again";
// Write out the contents of the first page
// Output=Changed web text
Console.WriteLine ("originalWebPage={0}", originalWebPage.Text);
}
}