Каков тип возвращаемого конструктора в C#?

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

я получил некоторые ответы на 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;
    }
}

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

3 ответов


по словам Спецификация Языка C# 4.0, секция 1.6:

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

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

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

  • если T - это класс-тип:

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

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

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

  • [...]

это означало бы, что конструктор per se не имеет типа возвращаемого значения (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, ключевое слово return не должно сопровождаться выражением объекта.")

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

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

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

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


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

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

на уровне семантики, в которой C# выражает намерение программистов, конструкторы не имеют возвращаемых типов. У них даже нет void. У них такой же тип возврата, как и у вас.

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

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

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

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