2013-06-06 65 views
11

Nếu bạn đã tuyên bố một struct:Tạo mới một cấu trúc rỗng làm gì trong C#?

struct EmptyResult 
{ 
} 

kết quả của việc tạo ra một biến kiểu EmptyResult trong một thể hiện là gì?

public Foo() 
{ 
    EmptyResult result; 
} 

Bạn có mong đợi phân bổ trên ngăn xếp hay nó có hiệu quả không?

+0

Tôi hy vọng trình biên dịch sẽ tối ưu hóa điều này. Đặt một điểm break trên dòng đó trong Foo và xem hit của nó? – Sayse

+0

... – James

+0

Nó sẽ được tối ưu hóa nếu bạn tạo biến kiểu 'int'. Có lẽ một ví dụ tốt hơn sẽ liên quan đến việc chuyển cấu trúc đến một hàm. –

Trả lời

9

Trình biên dịch C# buộc một cấu trúc trống để có kích thước 1 byte. Bạn có thể thấy điều này nếu bạn có một cái nhìn tại các struct trong một decompiler:

[StructLayout(LayoutKind.Sequential, Size=1)] 
private struct EmptyResult 
{ 
} 

Vì vậy, bất kỳ trường hợp mà struct trong một lớp học hoặc trên stack sẽ chiếm 1 byte, chính xác giống như một thể hiện của System.Byte hoặc System.SByte

+1

Có lẽ nó làm như vậy để có thể lấy địa chỉ của nó. –

+0

Bạn không cần phải dịch ngược. Bạn có thể sử dụng 'Marshal.SizeOf (typeof (EmptyResult))'. Tôi vừa mới đăng bài, nhưng đã quá chậm. –

+1

@DavidHeffernan Tôi chắc chắn bạn đã đúng - vì vậy bạn có thể lấy địa chỉ của nó, nhưng cũng để hai trường hợp có địa chỉ khác nhau. Điều thú vị là, [Stroustrup đề cập rằng về các cấu trúc C++ trống] (http://www.stroustrup.com/bs_faq2.html#sizeof-empty). –

1

Tôi nghĩ rằng đó là phân bổ ngăn xếp, phù hợp với cách các loại không tham chiếu hoạt động.

+1

Nhưng kích thước của cấu trúc là 0 byte; làm thế nào để bạn phân bổ 0 byte? – Servy

+0

Trong C++, nó chiếm một byte. – aquaraga

3

AC# struct không có trường nào vẫn có kích thước 1. Lý do là trình biên dịch phải có khả năng lấy địa chỉ của một cấu trúc sử dụng toán tử & trong mã không an toàn.

Tôi hy vọng loại cấu trúc của bạn sẽ được xử lý chính xác giống như kiểu byte.

1

Nếu bạn sử dụng idlasm.exe để nghiên cứu il, tại dòng mà bạn tạo ra một thể hiện của các Empty struct, bạn sẽ thấy:

.maxstack 1 
.locals init ([0] valuetype Draft.Empty e) 

Và định nghĩa của Empty struct là:

.class private sequential ansi sealed beforefieldinit Draft.Empty 
     extends [mscorlib]System.ValueType 
{ 
    .pack 0 
    .size 1 
} // end of class Draft.Empty 

Như bạn thấy nó phân bổ 1 byte tại thời gian tạo và trong định nghĩa kích thước của loại này là 1.

Vì vậy, có; nó phân bổ 1 byte trên stack.

Lưu ý: định nghĩa của Empty được trích xuất từ ​​cụm được biên dịch trong chế độ phát hành.

+0

Giai đoạn JIT có thể tối ưu hóa nó đi tất nhiên –

+0

@DavidHeffernan Tôi sẽ tìm hiểu điều gì đó nếu bạn vui lòng giải thích làm thế nào 'new Empty(). Equals (new Empty())' trả về true. Liệu nó không cần một địa chỉ thực tế trên ngăn xếp? (Tôi thực sự không quen thuộc với công việc JIT); Cảm ơn –

+0

'Equals()' kiểm tra giá trị bình đẳng cho cấu trúc. Vì không có trường nào nên trường hợp 's1.Equals (s2)' luôn luôn là' true' cho các toán hạng của kiểu 'EmptyResult'. –

Các vấn đề liên quan