我是否实例化了一个void的对象

本文关键字:一个 void 对象 是否 实例化 | 更新日期: 2023-09-27 18:04:31

大家都知道,在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的真实实例吗

我是否实例化了一个void的对象

从我所看到的,这是一个非常好的,完全有效的 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,应该在较新的版本中修复)

好吧,我想实例是错误的词。如果使用GetUninitializedObject创建对象,就会得到一个从方法名中提到的初始化对象。因此,假设您有一个类Foo,其中有一些成员,这些成员都没有任何值,因为没有调用构造函数。虽然Void甚至没有任何构造函数,但您不能在其上调用Activator.CreateInstance或使用new void()。然而,使用前面提到的不使用任何构造函数的方法,您可以创建它的对象,但将其保持初始化。这是一个特殊情况,让一个新对象保持单位化。

如果这是一个bug,一个特性或者其他什么我只能猜测。

编辑:显然这是一个功能,以下来自MSDN让我假设是这样的:

当前方法只能在用户打算立即填充所有字段时用于反序列化。(https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject%28v=vs.110%29.aspx)

因此,虽然您可以使用此方法创建实例,但您应该只在调用后立即提供所有必要的信息时才这样做。然而,void没有任何成员,它的状态仍然是无效的。