2015-07-24 20 views
7

Như bạn đã biết, trong C# chúng ta không thể làm điều gì đó như thế này:Tôi có khởi tạo một đối tượng trống không?

var voidObject = new void(); 

hoặc

var voidObject = new System.Void(); 

hoặc

var voidObject = Activator.CreateInstance(typeof(void)); 

Nhưng điều này mã biên dịch thành công và trong chế độ gỡ lỗi tôi có thể thấy loại số voidObjectSystem.Void:

var voidObject = FormatterServices.GetUninitializedObject(typeof(void)); 

Đây là gì? Đây có phải là ví dụ thực sự của void không?

+1

Wow ... Hoàn toàn vô dụng nhưng đáng kinh ngạc :-) Họ quên để đóng tuyến đường đó :-) – xanatos

+0

Tôi nhận được 'Biểu thức này đã được đánh giá và không có giá trị' –

+0

Bật .NET https://dotnetfiddle.net/BUUdKU và trên Mono https://ideone.com/LegWvM – xanatos

Trả lời

3

Từ những gì tôi có thể nhìn thấy nó là một cách hoàn hảo tốt, hoàn toàn hợp lệ đóng hộpSystem.Void kiểu giá trị :-)

Bạn có thể

Console.WriteLine(voidObject.GetType()); 

và thấy rằng nó là một System.Void.

System.Void là một loại giá trị, vì vậy tạo ra nó thông qua FormatterServices.GetUninitializedObject nên bằng làm (object)default(void) (vì FormatterServices.GetUninitializedObject sẽ trả về một kiểu giá trị với tất cả các lĩnh vực của nó đặt giá trị mặc định của họ) (lưu ý rằng rõ ràng (object)default(void) là bất hợp pháp).

Tuy nhiên không có nhiều điều bạn có thể làm với bạn đóng hộpSystem.Void ...

var voidObject = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(void)); 
var voidObject2 = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(void)); 

Console.WriteLine("Type: {0}", voidObject.GetType()); 
Console.WriteLine("IsValueType: {0}", voidObject.GetType().IsValueType); 

Console.WriteLine("Equals: {0}", voidObject.Equals(voidObject2)); 
Console.WriteLine("GetHashCode1: {0}", voidObject.GetHashCode()); 
Console.WriteLine("GetHashCode2: {0}", voidObject2.GetHashCode()); 
Console.WriteLine("ToString: {0}", voidObject.ToString()); 

Dường như có một số khác biệt giữa .NETMono triển khai ... Bật.NET tất cả các trường hợp của System.Void có cùng một GetHashCode(), trong khi trên Mono mỗi một trong số chúng có một khác nhau GetHashCode(). Các Equals hoạt động chính xác (true) cho cả hai.

(lưu ý rằng sự khác biệt trong GetHashCode() có vẻ là một lỗi của Mono với struct s mà không lĩnh vực: https://ideone.com/t0t8I6 rằng should be fixed trong phiên bản mới hơn)

0

Vâng, Imstance là từ không đúng tôi đoán. Nếu bạn tạo một đối tượng bằng cách sử dụng GetUninitializedObject, bạn sẽ nhận được một đối tượng được đơn vị hóa như tên phương thức rom đã đề cập. Vì vậy, giả sử bạn có một lớp Foo với một số thành viên không ai trong số những thành viên đó sẽ có bất kỳ giá trị nào vì hàm tạo không được gọi. Trong khi Void thậm chí không có bất kỳ hàm tạo nào, bạn có thể không gọi Activator.CreateInstance trên đó hoặc sử dụng new void(). Tuy nhiên với cách tiếp cận được đề cập mà không sử dụng bất kỳ nhà xây dựng nào bạn tạo ra một đối tượng của nó nhưng để nó được đơn vị hóa. Vì vậy, đây chỉ là một trường hợp đặc biệt để rời khỏi một đối tượng mới được đơn lẻ hóa.

Nếu đây là lỗi, tính năng hoặc bất kỳ điều gì tôi chỉ có thể đoán.

EDIT: Obviosuly Nó rất một tính năng, sau đây từ MSDN cho phép tôi giả định như vậy:

Phương pháp hiện tại chỉ nên được sử dụng cho deserialization khi người dùng có ý định ngay lập tức cư tất cả các lĩnh vực. (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject%28v=vs.110%29.aspx)

Vì vậy, trong khi bạn CÓ THỂ tạo cá thể bằng phương pháp này, bạn chỉ nên thực hiện khi cung cấp tất cả thông tin cần thiết ngay sau cuộc gọi. Tuy nhiên, do đó void không có bất kỳ thành viên nào trạng thái của nó vẫn không hợp lệ.

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