Каков тип возвращаемого конструктора в 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 " из вышеупомянутых способов рассмотрения вопроса.