Chúng bị hạn chế hơn. Bạn có thể nói ++ trên một con trỏ, nhưng không phải trên một số ref
hoặc out
.
EDIT Một số nhầm lẫn trong các ý kiến, vì vậy để được hoàn toàn rõ ràng: Vấn đề ở đây là so sánh với khả năng của con trỏ. Bạn không thể thực hiện thao tác tương tự như ptr++
trên ref
/out
, nghĩa là đặt địa chỉ đó ở vị trí lân cận trong bộ nhớ. Đó là sự thật (nhưng không liên quan ở đây) mà bạn có thể thực hiện tương đương với (*ptr)++
, nhưng đó sẽ là để so sánh nó với các khả năng của giá trị, không phải con trỏ.
Đó là một cược an toàn mà họ nội chỉ con trỏ, bởi vì chồng không được di chuyển và C# được tổ chức cẩn thận để ref
và out
luôn đề cập đến một khu vực hoạt động của ngăn xếp.
EDIT Để được hoàn toàn rõ ràng một lần nữa (nếu đó là chưa rõ ràng từ các ví dụ dưới đây), các Vấn đề ở đây không phải là ref
/out
thể chỉ điểm vào stack. Đó là khi nó trỏ đến ngăn xếp, nó được đảm bảo bởi các quy tắc ngôn ngữ không trở thành một con trỏ lơ lửng. Đảm bảo này là cần thiết (và có liên quan/thú vị ở đây) vì ngăn xếp chỉ loại bỏ thông tin theo lối thoát cuộc gọi phương thức, không có séc để đảm bảo rằng mọi liên kết giới thiệu vẫn tồn tại.
Ngược lại khi ref
/out
đề cập đến các đối tượng trong đống GC, không có gì ngạc nhiên khi các đối tượng đó có thể được giữ sống miễn là cần thiết: heap GC được thiết kế chính xác cho mục đích giữ lại đối tượng trong bất kỳ khoảng thời gian nào yêu cầu bởi các liên kết giới thiệu của chúng và cung cấp tính năng ghim (xem ví dụ bên dưới) để hỗ trợ các tình huống mà đối tượng không được di chuyển bằng cách nén GC.
Nếu bạn từng chơi với interop trong mã không an toàn, bạn sẽ thấy rằng ref
liên quan rất chặt chẽ đến con trỏ.Ví dụ, nếu một giao diện COM được khai báo như thế này:
HRESULT Write(BYTE *pBuffer, UINT size);
Các Interop Assembly sẽ biến nó thành này:
void Write(ref byte pBuffer, uint size);
Và bạn có thể làm điều này để gọi nó (tôi tin rằng những thứ COM interop chăm sóc ghim mảng):
byte[] b = new byte[1000];
obj.Write(ref b[0], b.Length);
Nói cách khác, ref
để byte đầu tiên giúp bạn truy cập vào tất cả; nó dường như là một con trỏ đến byte đầu tiên.
Bạn có thể '+ +' trên đối số 'ref' tốt, nhưng nó không có nghĩa là giống nhau. –
Ngoài ra, "' ref' và 'out' luôn đề cập đến một vùng hoạt động của ngăn xếp" là hoàn toàn sai. Ví dụ của bạn tạo một 'ref' thành một đối tượng trên gc heap. –