2015-07-24 2 views
7

Как вы знаете, в C# мы не могли сделать что-то вроде этого:Я создал экземпляр объекта пустоты?

var voidObject = new void(); 

или

var voidObject = new System.Void(); 

или

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

Но этот код компилируется успешно и в режиме отладки я может видеть, что этот тип voidObject составляет System.Void:

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

Что это? Это реальный пример void?

+1

Wow ... Полностью бесполезный, но невероятно :-) Они забыли закрыть что маршрут :-) – xanatos

+0

Я получил это выражение было оценено и не имеет значения –

+0

На. NET https://dotnetfiddle.net/BUUdKU и на Моно https://ideone.com/LegWvM – xanatos

ответ

3

Из того, что я могу видеть, что это совершенно хорошо, отлично действует боксировалSystem.Void тип значения :-)

Вы можете

Console.WriteLine(voidObject.GetType()); 

и видеть, что это System.Void.

System.Void является типом значения, поэтому его создание через FormatterServices.GetUninitializedObject должно быть равно делать (object)default(void) (потому что FormatterServices.GetUninitializedObject возвращает значение типа со всеми полями, установленных в их значение по умолчанию) (обратите внимание, что явно (object)default(void) является незаконным).

Еще есть не так много вещей, которые вы можете сделать с вашими штучногоSystem.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()); 

Там, кажется, некоторые различия между .NET и Mono реализациями ... On.NET все экземпляры System.Void имеют одинаковые GetHashCode(), а на Mono каждый из них имеет GetHashCode(). Equals работает правильно (true) для обоих из них.

(обратите внимание, что разница в GetHashCode() кажется ошибка в Mono с struct с без полей: https://ideone.com/t0t8I6 что should be fixed в новых версиях)

0

Ну, Imstance - это странное слово, которое я предполагаю. Если вы создаете объект с помощью GetUninitializedObject, вы получаете объект-унификатор, как указано имя метода rom. Предположим, что у вас есть класс Foo с некоторыми членами, ни один из этих членов не будет иметь никакого значения, потому что конструктор не вызывается. В то время как у Void даже нет конструктора, вы можете не позвонить по телефону Activator.CreateInstance или использовать new void(). Однако при упомянутом подходе, который не использует какой-либо конструктор, вы создаете его объект, но оставляете его униализованным. Таким образом, это всего лишь частный случай выхода из нового объекта unititialzed.

Если это ошибка, функция или что-то еще, что я могу только догадываться.

EDIT: Obviosuly подмигнули функцию, следующее из MSDN позволяет мне предположить, так:

Текущий метод должен использоваться только для десериализации, когда пользователь хочет немедленно заполнить все поля. (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject%28v=vs.110%29.aspx)

Таким образом, пока вы можете создать экземпляр, используя этот метод, вы должны сделать это только после предоставления всей необходимой информации сразу после вызова. Однако, следовательно, у void нет пользователей, состояние которых по-прежнему недействительно.