Bằng cách giải thích, hãy loại giá trị này trong C#:Có thể tạo chu trình tham chiếu chỉ sử dụng các loại giá trị không?
struct ObjRef
{
public object Value;
public ObjRef(object value) { Value = value; }
}
tôi có thể tưởng tượng một đồ thị đối tượng nơi có hai đóng hộp trường thuộc loại này, từng nắm giữ một tham chiếu đến người kia. Đây là những gì tôi có ý nghĩa bởi một chu trình tham chiếu chỉ với các kiểu giá trị.
Câu hỏi của tôi là liệu biểu đồ đối tượng đó có thể được xây dựng trong .NET hay không. Về mặt khái niệm, việc xây dựng, nếu nó tồn tại, sẽ như sau:
object left = new ObjRef();
object right = new ObjRef(left);
left.Value = right;
nhưng rõ ràng, dòng cuối cùng không có giá trị C#. Đặt dòng cuối cùng:
((ObjRef)left).Value = right;
không đạt được kết quả như hộp bỏ unbox left
và bạn sẽ tắt một bản sao. Vì vậy, ít nhất trong C# thẳng, nó không giống như xây dựng là có thể.
Có ai biết liệu xây dựng có thể đạt được bằng cách sử dụng phản chiếu, mã không an toàn, dynamic
, mã IL hoặc theo bất kỳ cách nào khác không? Hoặc, bất cứ ai có thể cho thấy rằng CLR có hiệu quả ngăn chặn một chu kỳ tham chiếu?
Xin lưu ý rằng tôi không thực sự muốn tạo biểu đồ đối tượng như vậy. Thay vào đó, câu trả lời có thể ảnh hưởng đến việc thiết kế các thuật toán làm việc với các đồ thị đối tượng, chẳng hạn như các trình định dạng tuần tự hóa/deserialization.
EDIT
Như Brian đề nghị, nó thực sự có thể thay đổi giá trị đóng hộp mà không unboxing nó, bằng cách đúc nó vào một loại giao diện thay vì kiểu giá trị. Vì vậy, cho mã này:
interface IObjRef
{
IObjRef Value { get; set; }
}
struct ObjRef : IObjRef
{
IObjRef value;
public IObjRef Value { get { return value; } set { this.value = value; } }
public ObjRef(IObjRef value) { this.value = value; }
}
sau đó tham chiếu vòng tôi mô tả có thể được xây dựng như thế này:
IObjRef left = new ObjRef();
IObjRef right = new ObjRef(left);
left.Value = right;
Mà về cơ bản lá chúng tôi với lý do # 72 lý do tại sao có thể thay đổi giá trị loại là ác.
Nó không có lợi thế chút nào; như tôi đã nói trong câu hỏi, tôi không muốn tạo chu kỳ này. Ngoài ra, tôi không bao giờ viết một loại giá trị có thể thay đổi được. Tuy nhiên, một trình định dạng tuần tự làm việc trên các đồ thị đối tượng tùy ý phải nhận thức được khả năng, và không nhập một vòng lặp vô hạn bằng cách giả định rằng các kiểu tham chiếu luôn tạo thành cây chứ không phải chu kỳ. Nó cũng có thể ảnh hưởng đến thứ tự các đối tượng phải được deserialized. –
Ngẫu nhiên, các loại giá trị đóng hộp không thực sự là loại giá trị. Trong CLR, chúng được xử lý như các lớp, và chúng hoạt động giống như các lớp. Điều duy nhất khiến chúng đặc biệt là * các vị trí lưu trữ * có kiểu khai báo xuất phát từ kiểu giá trị sẽ giữ dữ liệu cho một mục thay vì tham chiếu đối tượng. – supercat