Did I instantiate an object of void?
As you all know, in C# we could not do something like this:
var voidObject = new void();
or
var voidObject = new System.Void();
or
var voidObject = Activator.CreateInstance(typeof(void));
But this code compiles successfully and in debug mode I can see that type of the voidObject
is System.Void
:
var voidObject = FormatterServices.GetUninitializedObject(typeof(void));
What is this? Is this real instance of void
?
From what I can see it is a perfectly good, perfectly valid boxed System.Void
value type :-)
You can
Console.WriteLine(voidObject.GetType());
and see that it is a System.Void
.
System.Void
is a value type, so creating it through FormatterServices.GetUninitializedObject
should be equal to doing (object)default(void)
(because FormatterServices.GetUninitializedObject
will return a value type with all its fields set to their default value) (note that clearly (object)default(void)
is illegal).
Still there are not many things you can do with your boxed 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());
There seems to be some differences between .NET and Mono implementations... On .NET all the instances of System.Void
have the same GetHashCode()
, while on Mono every one of them has a different GetHashCode()
. The Equals
works correctly ( true
) for both of them.
(note that the difference in the GetHashCode()
seems to be a bug of Mono with struct
s without fields: https://ideone.com/t0t8I6 that should be fixed in newer releases)
Well, Imstance is the whrong word I guess. If you create an object by using GetUninitializedObject
you get an unitialized object as mentioned rom methods name. So assume you have a class Foo
with some members none of those members would have any value because the constructor is not called. While Void
not even has any constructor you may not call Activator.CreateInstance
on it or use new void()
. However with the mentioned approach that does not use any constructor you create an object of it but leave it unitialized. So this is just a special case of leaving a new object unititialzed.
If this is a bug, a feature or whatever I can only guess.
EDIT: Obviosuly it´sa feature, the following from MSDN lets me assume so:
The current method should only be used for deserialization when the user intends to immediately populate all fields. (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject%28v=vs.110%29.aspx)
So while you CAN create an instance using this method you should only do it when providing all necessary information immediatly after the call. However hence void
does not have any members its state is still invalid.
上一篇: 在打盹模式下的Android VOIP应用程序行为
下一篇: 我是否实例化了一个void对象?