什么是在C#中的构造函数的返回types?
我在这个链接上提出了Java的这个问题
我在java.Now中得到了一些答案,我想知道它在C#中。
正如我们所知,我们不必将任何返回types添加到C#构造函数中。
class Sample{ ..... Sample(){ ........ } }
在Objective C中,如果我们创build一个构造函数,它会返回一个指向它的类的指针。 但我认为这不是强制性的。
AClass *anObject = [[AClass alloc] init];//init is the constructor with return type a pointer to AClass
同样,是构造函数转换为一个方法,返回对自己的类的引用?
喜欢这个:
class Sample{ ..... Sample Sample(){ ........ return this; } }
编译器是否将一个返回types的引用添加到构造函数的同一个类中? 发生了什么构造函数? 任何参考去研究这个?
根据C#4.0语言规范 ,第1.6节:
类的实例是使用
new
运算符创build的,该运算符为新实例分配内存,调用构造函数初始化实例,并返回对实例的引用。
负责分配内存的new
运算符,将新分配的对象的引用传递给构造函数,然后返回实例的引用。 第7.6.10.1节也解释了这种机制:
new T(A)
formsnew T(A)
的对象创buildexpression式的运行时处理,其中T
是类types或结构types ,A
是可选参数列表 ,包含以下步骤:
如果
T
是一个类的types :
T
类的新实例被分配。 如果没有足够的可用内存分配新实例,则抛出System.OutOfMemoryException
,并且不会执行进一步的步骤。新实例的所有字段都被初始化为默认值(第5.2节)。
实例构造函数根据函数成员调用的规则调用(第7.5.4节)。 对新分配的实例的引用会自动传递给实例构造函数,并且可以从该构造函数中访问该实例。
[…]
这意味着构造函数本身没有返回types( void
)。
InBetween的答案是正确的。 我也不同意在MSDN论坛上讨论的内容。 如果我们看一个非常简单的代码示例,如下所示:
void Main() { var a = new A(); var message = a.GetAs(); } public class A { private readonly string someAs; public A() { someAs = "AaaaaAAAAAaaAAAAAAAaa"; return; } public String GetAs() { return someAs; } }
和相应的IL:
IL_0000: newobj UserQuery+A..ctor IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: callvirt UserQuery+A.GetMessage A.GetMessage: IL_0000: ldarg.0 IL_0001: ldfld UserQuery+A.someAs IL_0006: ret A..ctor: IL_0000: ldarg.0 IL_0001: call System.Object..ctor IL_0006: ldarg.0 IL_0007: ldstr "AaaaaAAAAAaaAAAAAAAaa" IL_000C: stfld UserQuery+A.someAs IL_0011: ret
那么立刻就会清楚,.ctor返回void
。 (如果你试图从构造函数中返回一些东西,也可以很容易地看到这个,也就是说,如果你做了类似于public A() { return this; }
的东西,编译器就会抱怨并且说类似于“因为A()返回void,关键字后面不能有对象expression式。“)
更进一步:你可以看到这个expression式new A()
被转换为下面的IL: newobj UserQuery+A..ctor
。 “通用语言基础设施参考资料”中有关于newobj
(第4.20节)的内容如下:
newobj指令分配与构造函数关联的类的新实例,并将新实例中的所有字段初始化为0(适当types)或null(适当时)。 然后调用具有给定参数的构造函数以及新创build的实例。 构造函数被调用后,现在初始化的对象引用被压入堆栈。
(通过与Objective-C的比较:new / newobj是对于分配消息的模拟,而构造器是对init
消息的模拟。)
所以它真的是new
运算符返回一个引用到新构造的对象,而不是构造函数本身。
这取决于你怎么看了。
“返回types”与其他任何概念一样。
在C#expression程序员意图的语义层次上,构造函数没有返回types。 他们甚至没有void
。 他们没有比你更多的回报。
这些构造函数将被编译为IL,返回types为void
。
如果你调用一个ConstructorInfo
你会得到一个types的对象(尽pipe这个object
的返回types是object
,你必须转换为相关的types)。
最接近具体含义的是要调用构造函数来处理堆栈的细节。 这里虽然你可以争辩说,虽然引用types“返回”了适当types的引用,但是由于它将值放入堆栈,因此值types不会处理已经存在于堆栈上的值。 或者你可以说这两个都是实现细节,而不是真的回答这个问题。
“没有返回types”可能是上述查看问题的方式中最“C#ish”的。