大家都知道,在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
的真实实例吗?
答案 0 :(得分: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实现之间似乎存在一些差异......在.NET上,System.Void
的所有实例都具有相同的GetHashCode()
,而在Mono上其中一个有不同的GetHashCode()
。 Equals
对两者都正常(true
)。
(请注意,GetHashCode()
的差异似乎是Mono的错误,struct
s没有字段:https://ideone.com/t0t8I6 should be fixed在较新版本中
答案 1 :(得分:0)
嗯,Imstance是我猜的错误词。如果使用GetUninitializedObject
创建对象,则会获得一个如提到的rom方法名称的单元化对象。因此,假设您有一个类Foo
,其中一些成员没有任何值,因为没有调用构造函数。虽然Void
甚至没有任何构造函数,但您可能无法在其上调用Activator.CreateInstance
或使用new void()
。但是,如果提到的方法不使用任何构造函数,则可以创建它的对象,但将其保持为单元化。所以这只是将新对象单元化的特殊情况。
如果这是一个错误,一个功能或我只能猜测的任何内容。
编辑:显然这是一个功能,MSDN中的以下内容让我这样假设:
当用户打算立即填充所有字段时,当前方法只应用于反序列化。 (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject%28v=vs.110%29.aspx)
因此,当您使用此方法创建实例时,您应该只在通话后立即提供所有必要信息时才这样做。但是因此void
没有任何成员,其状态仍然无效。