C#中构造函数的返回类型是什么?

son*_*mas 45 c# constructor

我已在链接上向Java提出此问题

我在java中得到了一些答案.现在我想在C#中知道它.

我们知道,我们不必向C#构造函数添加任何返回类型.

class Sample{
  .....
  Sample(){
    ........
  }
}
Run Code Online (Sandbox Code Playgroud)

在Objective C中,如果我们创建一个构造函数,它会返回一个指向其类的指针.但我认为这不是强制性的.

AClass *anObject = [[AClass alloc] init];//init is the constructor with return type a pointer to AClass
Run Code Online (Sandbox Code Playgroud)

类似地,构造函数是否转换为返回对其自己的类的引用的方法?

像这样:

class Sample{
    .....
    Sample Sample(){
      ........

      return this;
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器是否向构造函数添加了对同一类的引用的返回类型?构造函数发生了什么?有没有参考研究这个?

InB*_*een 47

根据C#4.0语言规范,第1.6节:

类的实例是使用new运算符创建的,该运算符为新实例分配内存,调用构造函数初始化实例,并返回对实例的引用.

这是new谁负责分配内存,传递新分配的对象的参考构造函数,然后返回实例的引用的运营商.第7.6.10.1节还解释了这种机制:

表单 的对象创建表达式的运行时处理new T(A),其中T类型结构类型,并且A是可选的 参数列表,包括以下步骤:

  • 如果T类型:

    • T分配了一个新的类实例.如果没有足够的可用内存来分配新实例, System.OutOfMemoryException则抛出a并且不执行进一步的步骤.

    • 新实例的所有字段都初始化为其默认值(第5.2节).

    • 根据函数成员调用(第7.5.4节)的规则调用实例构造函数.对新分配的实例的引用会自动传递给实例构造函数,并且可以从该构造函数中访问该实例this.

  • [...]

这意味着构造函数本身没有返回类型(void).

  • @sonuthomas:您不必接受评分最高的答案,只需选择最能帮助您的答案或最好地回答您的问题(在您看来).请参阅[如何接受答案?](http://meta.stackexchange.com/q/5234) (3认同)

afr*_*hke 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

和相应的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
Run Code Online (Sandbox Code Playgroud)

然后它立即变得清晰,.ctor返回void.(如果你试图从构造函数中返回一些内容,也可以很容易地看到这一点,即如果你做了类似public A() { return this; }编译器的事情会抱怨并说出类似"因为A()返回void,返回关键字后面不能跟一个对象表达式".)

进一步:您可以看到此表达式new A()被转换为以下IL : newobj UserQuery+A..ctor. "公共语言基础结构参考"说明如下newobj(第4.20节):

newobj指令分配与构造函数关联的类的新实例,并将新实例中的所有字段初始化为0(正确类型)或适当时为null.然后,它使用给定的参数和新创建的实例调用构造函数.调用构造函数后,现在初始化的对象引用将被压入堆栈.

(通过与Objective-C的比较:new/newobj是alloc消息的模拟,而构造函数是init消息的模拟.)

所以它确实是new运算符返回对新构造的对象的引用,而不是构造函数本身.