2013-01-13 20 views
8
public struct Unit 
{ 
    Unit u; 
} 

Nguyên nhân:Tại sao không có vấn đề bố trí cyclic cho các lớp trong C#?

Struct viên 'Unit.u' kiểu 'Đơn vị' gây ra một chu kỳ trong struct bố trí.

Nhưng

public class Unit 
{ 
    Unit u; 
} 

biên dịch. Tôi hiểu vấn đề tôi cho là vậy. Một chu kỳ vô tận sẽ được hình thành khi tham chiếu một đối tượng Unit vì nó sẽ phải khởi tạo một thành viên khác Unit và cứ tiếp tục như vậy. Nhưng tại sao trình biên dịch hạn chế vấn đề chỉ cho structs? Vấn đề không còn tồn tại cho class nữa không? Tui bỏ lỡ điều gì vậy?

Trả lời

20

Sự cố là về bố cục .

Khi Unit là cấu trúc, bất kỳ giá trị nào cho một Unit sẽ phải chứa một giá trị khác cùng loại (và do đó cùng kích thước), quảng cáo vô hạn. Không thể nào. Tôi cho rằng bạn có thể tranh luận rằng không có trường nào khác, các trường cho Unit sẽ không chiếm bộ nhớ, vì vậy bạn có thể chứa nó trong chính nó - nhưng tôi tin rằng cách CLR hoạt động đảm bảo rằng tất cả các cấu trúc đều chiếm ít nhất 1 byte. ..

Khi Unit là một lớp học, một đối tượng Unit chỉ phải chứa tham khảo đến một đối tượng Unit. Không có vấn đề về bộ nhớ và giá trị có thể là null để bắt đầu.

Hãy suy nghĩ theo cách này: bạn không thể có một căn nhà chứa một ngôi nhà khác được xây dựng từ cùng một bản thiết kế, nhưng bạn chắc chắn có một căn nhà chứa một tờ giấy có địa chỉ nhà tương tự trên đó ...

+0

Ồ đúng vậy. Din nghĩ rằng xa .. Cảm ơn. – nawfal

+0

@Jon, ví dụ về ngôi nhà thực sự tuyệt vời! :) – nawfal

+1

Giải thích ngắn gọn trong bit cuối cùng. +1 –

3

Lớp là loại tham chiếu, vì vậy tôi tưởng tượng sự khác biệt là trong ví dụ class, nó chỉ phải lưu tham chiếu đến một phiên bản khác. Đối với struct của bạn, một loại giá trị, nó sẽ cần phải bao gồm toàn bộ cấu trúc một lần nữa, do đó một vòng lặp vô hạn.

1

Structvalue type. Unit có thể giữ giá trị như chính nó? Tôi nghĩ rằng điều này không phải là posible.

Nhưng khi Unitclass, classreference type. Unit đối tượng có thể chứa tham chiếu đối tượng khác Unit. Nó ổn.

2

Các struct được tự động khởi tạo với một giá trị, vì vậy trong ví dụ của bạn một giá trị Unit chứa một giá trị Unit, trong đó có một giá trị Unit, trong đó có một giá trị Unit, vv ...

dụ class của bạn chỉ khởi tham chiếu đến null, không có biến hồi vô hạn.tuy nhiên bạn sẽ gặp phải một vấn đề tương tự nếu bạn đã làm như sau:

class Unit 
{ 
    Unit mUnit = new Unit(); 
} 

Bây giờ, xây dựng một Unit xây dựng một Unit, mà xây dựng một Unit, vv ... Trong trường hợp này, bạn sẽ gặp phải một ngoại lệ tràn runtime chồng nếu/khi bạn cố gắng khởi tạo đối tượng Unit.

Tôi nghĩ rằng bạn có thể tránh được sự cố struct bằng cách sử dụng loại có thể vô hiệu hóa nhưng vấn đề vẫn còn. Tôi tin rằng điều này là do thực tế rằng struct có thể vô hiệu hóa vẫn được khởi tạo khi được đặt thành null.

+1

Cả hai giả định của bạn là sai trong thực tế. Chỉnh sửa nó. Với cái đầu tiên tôi có nghĩa là không có bất kỳ cảnh báo thời gian biên dịch nào giống như trong các cấu trúc. – nawfal

+0

@nawfal bạn có thể cụ thể hơn không? –

+0

Tôi không nói rằng bạn sẽ nhận được cảnh báo thời gian biên dịch, tôi đã nói bạn sẽ bị tràn ngăn xếp. –