Подтвердить что ты не робот

Каков тип возврата конструктора в С#?

Я задал этот вопрос для Java на этой ссылке

Я получил несколько ответов в java.Now, я хочу знать это на С#.

Как нам известно, нам не нужно добавлять какой-либо тип возвращаемого значения в конструктор С#.

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;
    }
}

Составляет ли компилятор возвращаемый тип ссылку на тот же класс на конструктор? Что происходит с конструктором? Любая ссылка, чтобы изучить это?

4b9b3361

Ответ 1

В соответствии с Спецификацией языка С# 4.0, раздел 1.6:

Экземпляры классов создаются с помощью оператора new, который выделяет память для нового экземпляра, вызывает конструктор для инициализации экземпляра и возвращает ссылку на экземпляр.

Это оператор new, который отвечает за выделение памяти, передачу ссылки на вновь выделенный объект на конструктор и последующее возвращение ссылки на экземпляр. Этот механизм также объясняется в разделе 7.6.10.1:

Обработка времени создания объекта-выражения формы new T(A), где T является классом или структурным типом, а A является необязательным Список аргументов состоит из следующих шагов:

  • Если T - тип класса:

    • Выделен новый экземпляр класса T. Если этого недостаточно памяти для размещения нового экземпляра, System.OutOfMemoryException выбрасывается, и никаких дальнейших шагов нет выполняется.

    • Все поля нового экземпляра инициализируются по умолчанию значения (§5.2).

    • Конструктор экземпляра вызывается в соответствии с правила вызова функции-члена (§7.5.4). Ссылка на новость выделенный экземпляр автоматически передается конструктору экземпляра и экземпляр может быть доступен изнутри этого конструктора как this.

  • [...]

Это означало бы, что сам конструктор не имеет типа возврата (void).

Ответ 2

Ответ 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, ключевое слово return не должно сопровождаться выражение объекта." )

Далее: вы можете видеть, что это выражение new A() переводится на следующий IL: newobj UserQuery+A..ctor. В "Справочнике об общей языковой инфраструктуре" говорится следующее о newobj (раздел 4.20):

Команда newobj выделяет новый экземпляр класса, связанного с конструктором, и инициализирует все поля в новом экземпляре равным 0 (соответствующего типа) или нулевым, если это необходимо. Затем он вызывает конструктор с заданными аргументами вместе с вновь созданным экземпляром. После того, как конструктор был вызван, теперь инициализированная ссылка на объект помещается в стек.

(В сравнении с Objective-C: new/newobj является аналогом сообщения alloc, а конструктор - аналогом сообщения init.)

Так что это действительно оператор new, который возвращает ссылку на вновь созданный объект, а не сам конструктор.

Ответ 3

Это зависит от того, как вы на это смотрите.

"Тип возврата" является таким же концептуальным, как и все остальное.

На уровне семантики, в которой С# выражает намерение программистов, конструкторы не имеют типов возврата. У них даже нет void. У них больше нет типа возврата, чем у вас.

ИЛ, эти конструкторы будут скомпилированы, имеют тип возврата void.

Если вы вызываете ConstructorInfo, вы получаете объект соответствующего типа (хотя тип возвращаемого значения при вызове object и вы должны использовать его для соответствующего типа).

Ближайшая вещь к конкретному значению для возврата - это детали того, как стек манипулируется вызываемым конструктором. Здесь, хотя вы можете утверждать, что, хотя ссылочный тип "возвращает" ссылку соответствующего типа, поскольку он помещает значение в стек, тип значения не работает, так как он манипулирует значениями, уже присутствующими в стеке. Или вы можете просто утверждать, что оба являются деталями реализации, и вообще не отвечают на вопрос.

"Не имеет типа возврата", вероятно, является наиболее "С# ish" из вышеуказанных способов рассмотрения вопроса.