我已在this链接
上向Java提出此问题我在java中得到了一些答案。现在我想在C#中知道它。
我们知道,我们不必向C#构造函数添加任何返回类型。
class Sample{
.....
Sample(){
........
}
}
在Objective C中,如果我们创建一个构造函数,它会返回一个指向其类的指针。但我认为这不是强制性的。
AClass *anObject = [[AClass alloc] init];//init is the constructor with return type a pointer to AClass
类似地,构造函数是否转换为返回对其自己的类的引用的方法??
像这样:
class Sample{
.....
Sample Sample(){
........
return this;
}
}
编译器是否向构造函数添加了对同一类的引用的返回类型? 构造函数发生了什么? 有没有参考研究这个?
答案 0 :(得分:46)
根据 C#4.0语言规范,第1.6节:
使用
new
运算符创建类实例,该运算符为新实例分配内存,调用构造函数初始化实例,并返回对实例的引用。
负责分配内存的new
运算符,将新分配的对象的引用传递给构造函数,然后返回对实例的引用。这种机制也在第7.6.10.1节中解释:
表单的 object-creation-expression 的运行时处理
new T(A)
,其中T
是 class-type 或 struct-type ,A
是可选的 argument-list ,包含以下步骤:
如果
T
是类型:
分配了类
T
的新实例。如果还不够 可用于分配新实例的内存,a 抛出System.OutOfMemoryException
,没有进一步的步骤 执行。新实例的所有字段都初始化为默认值 值(§5.2)。
根据实例构造函数调用 函数成员调用规则(第7.5.4节)。对新的参考 已分配的实例会自动传递给实例构造函数 并且可以在该构造函数中访问该实例
this
。[...]
这意味着构造函数本身没有返回类型(void
)。
答案 1 :(得分:19)
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; }
这样的事情,编译器就会抱怨并说出像#34;自A( )返回void,返回关键字后面不能跟一个对象表达式。")
此外:您可以看到此表达式new A()
已转换为以下IL:newobj UserQuery+A..ctor
。 "公共语言基础设施参考"关于newobj
(第4.20节)说明如下:
newobj指令分配与构造函数关联的类的新实例,并将新实例中的所有字段初始化为0(正确类型)或适当时为null。然后,它使用给定的参数和新创建的实例调用构造函数。在调用构造函数之后,将现在初始化的对象引用推送到堆栈上。
(通过与Objective-C的比较:new / newobj与alloc
消息类似,构造函数与init
消息类似。)
所以它真的是new
运算符返回对新构造的对象的引用,而不是构造函数本身。
答案 2 :(得分:4)
这取决于你如何看待它。
“返回类型”与其他任何内容一样具有概念性。
在C#表达程序员意图的语义级别,构造函数没有返回类型。他们甚至没有void
。他们没有比你更多的回报类型了。
这些构造函数将被编译为IL,其返回类型为void
。
如果你调用ConstructorInfo
,你会得到一个有问题类型的对象(虽然该调用的返回类型是object
,你必须转换为相关类型。)
返回具体意义的最接近的事情是被调用的构造函数如何操纵堆栈的细节。这里虽然您可以争辩说,虽然引用类型“返回”相应类型的引用,但由于它将值放在堆栈中,因此值类型不会操作堆栈中已存在的值。或者你可以说两者都是实现细节,而不是真正回答这个问题。
“没有返回类型”可能是上述查看问题的方式中最“C#ish”。