Tôi đến từ C ++ và tìm thấy một hành vi rất khác nhau giữa các con trỏ trong C ++ và C #.
Tôi ngạc nhiên thấy mã này biên dịch ... Và thậm chí ... Hoạt động hoàn hảo.
class C
{
private readonly int x = 0;
unsafe public void Edit()
{
fixed (int* p = &x)
{
*p = x + 1;
}
Console.WriteLine($"Value: {x}");
}
}
Điều này làm tôi rất bối rối, ngay cả trong C ++, chúng tôi có một cơ chế để bảo vệ const
các đối tượng ( const
trong C ++ gần giống như readonly
trong C #, không phải const
trong C #), vì chúng tôi không có đủ lý do để tự ý sửa đổi giá trị const thông qua con trỏ.
Khám phá thêm, tôi thấy không có tương đương với con trỏ const cấp thấp của C ++ trong C #, sẽ giống như:
readonly int* p
trong C # nếu nó có một.
Sau đó p chỉ có thể đọc đối tượng được trỏ đến, và không thể ghi vào nó.
Và đối với const
các đối tượng, C # đã cấm các nỗ lực truy xuất địa chỉ của họ.
Trong C ++, mọi nỗ lực sửa đổi const
đều là lỗi biên dịch hoặc Hành vi không xác định. Trong C #, tôi không biết liệu có khả năng nào chúng ta có thể sử dụng điều này không.
Vì vậy, câu hỏi của tôi là:
- Là hành vi này thực sự được xác định rõ? Mặc dù tôi biết trong C # không có khái niệm như UB trong C ++
- Nếu vậy, tôi nên sử dụng nó như thế nào? Hoặc không bao giờ sử dụng nó?
Lưu ý: Trong phần bình luận: bỏ đi const
trong C ++ không liên quan đến câu hỏi này, bởi vì nó chỉ hợp lệ khi bản thân đối tượng chỉ không phải là đối tượng const
, nếu không thì đó là UB. Thêm vào đó, về cơ bản tôi đang nói về C # và biên dịch hành vi thời gian.
Bạn có thể yêu cầu tôi cung cấp thêm chi tiết nếu bạn không hiểu đầy đủ câu hỏi. Tôi thấy hầu hết mọi người không thể hiểu điều này một cách chính xác, có thể đó là lỗi của tôi không làm cho nó rõ ràng.