почему конструктор Int32 по умолчанию не имеет параметров?

int x = 6;

это работает, но

Int32 x = new Int32(6);

не. Почему конструктор Int32 по умолчанию не имеет параметров? как он присваивает x значение 6?

редактировать: больше пояснений. mscorlib/system/int32.cs,225942ed7b7a3252 строка 38:

internal int m_value;

как компилятор присваивает этому m_value 6? Конструктор Int32 не имеет параметров.


person csharp newbie    schedule 21.03.2018    source источник
comment
Это делается компилятором. Так что это подпольная магия, вот и все   -  person Evgeny Gorbovoy    schedule 21.03.2018
comment
Int32 x = new Int32(6); не то же самое, что int x = 6;. То же самое будет Int32 x = 6;, что точно работает, так как int — это просто псевдоним для Int32.   -  person L. Guthardt    schedule 21.03.2018
comment
Int32 - это удобный тип для представления целых чисел в объектной модели, но это не то, что язык и среда выполнения действительно используют при работе с целыми числами, поскольку они имеют встроенную поддержку для этого. int x = 6 преобразуется в ldc.i4.6, непосредственно создавая целочисленную константу, вообще не затрагивая тип структуры.   -  person Jeroen Mostert    schedule 21.03.2018
comment
Int32 х = 6? Это работает   -  person Alvarez    schedule 21.03.2018
comment
Я думаю, что System.Int32 даже не имеет конструктора без параметров.   -  person Tim Schmelter    schedule 21.03.2018
comment
@TimSchmelter - Все структуры имеют конструктор по умолчанию.   -  person Lee    schedule 21.03.2018
comment
@TimSchmelter все структуры имеют конструктор без параметров. Конечно, вы можете просто скомпилировать код, чтобы убедиться в этом самостоятельно, а не верить незнакомым людям в Интернете.   -  person Servy    schedule 21.03.2018
comment
@Servy: J.Skeet не чужой: stackoverflow.com/questions/333829/   -  person Tim Schmelter    schedule 21.03.2018
comment
@TimSchmelter Вы не можете определить свой собственный пользовательский конструктор без параметров для любой структуры. Он должен существовать, но его поведение нельзя изменить. Он может иметь только поведение по умолчанию. Тот факт, что вы не можете создать пользовательский конструктор без параметров или изменить его поведение, не означает, что его не существует.   -  person Servy    schedule 21.03.2018
comment
Примечание: в среде .Net конструктор по умолчанию по определению не имеет параметров.   -  person Zohar Peled    schedule 21.03.2018
comment
@Servy: вот еще один незнакомец из Интернета, который говорит, что в System.Int32 нет конструктора по умолчанию: stackoverflow.com/questions/25839595/   -  person Tim Schmelter    schedule 21.03.2018
comment
Следует ли считать, что Int32 имеет конструктор по умолчанию, это в основном точка зрения. Если вы спросите C#, то да, так как вы можете написать new Int32(). Если спросить рантайм, то нет, так как Int32 вообще не имеет конструкторов. Ни один конструктор никогда не вызывается, что имеет смысл, поскольку экземпляры Int32 не на самом деле задействованы при работе с целыми числами.   -  person Jeroen Mostert    schedule 21.03.2018
comment
@TimSchmelter Кто-то говорит, что об этом нет никакой информации. Он существует, и его можно использовать, просто о нем нет метаинформации. Опять же, если вы хотите увидеть, есть ли у него конструкция без параметров, просто попробуйте скомпилировать new Int32(); и посмотреть, говорит ли он вам, что такого конструктора не существует, это простой тест для выполнения.   -  person Servy    schedule 21.03.2018
comment
@Servy: это может быть магия компилятора, которая позволяет вам поверить, что он есть, когда на самом деле его нет   -  person Tim Schmelter    schedule 21.03.2018
comment
@TimSchmelter Вы можете посмотреть документацию, чтобы увидеть, что в ней прямо говорится, что все структуры имеют конструктор по умолчанию, если вам действительно важно, как он называется, чтобы увидеть, что он является на самом деле конструктором, я думаю, и что это не какой-то другой тип операции, который просто выглядит как конструктор (например, при написании new Action(someMethod);, который на самом деле не является конструктором).   -  person Servy    schedule 21.03.2018
comment
Обратите внимание, что newobj instance void [mscorlib]System.Int32::.ctor() недопустимо — вы можете собрать его, но во время выполнения вы получите MissingMethodException. Конечно, это не тот код, который на самом деле генерируется чем-либо, поскольку вы не создаете ints таким образом. Опять же: с точки зрения C# существует конструктор по умолчанию, поскольку все структуры имеют конструктор по умолчанию; с точки зрения IL, нет, и не требуется никакого типа, чтобы иметь конструктор. Обе точки зрения одинаково правомерны, если они четко обозначены.   -  person Jeroen Mostert    schedule 21.03.2018
comment
как компилятор присваивает 6 этому m_value - это не так. Когда среде выполнения будет предложено рассматривать int как экземпляр Int32, она позаботится о том, чтобы m_value отражало значение целого числа. Ни компилятор, ни среда выполнения не ограничены правилами C#, в отличие от программистов. Из соображений эффективности среда выполнения имеет специальную обработку для таких типов, как Int32. Вы даже не увидите явной ссылки на m_value в байт-коде — когда этот исходный код скомпилирован, компилятор знает, что нужно преобразовать его в целочисленные инструкции (используя ldind.i4, а не ldfld).   -  person Jeroen Mostert    schedule 21.03.2018
comment
Объявление для Int32, которое вы можете найти в исходном коде фреймворка, вводит в заблуждение. Они расставили точки над i и зачеркнули t, но компилятор и джиттер слишком много знают о Int32, чтобы когда-либо позволить этому коду работать. Некоторое значение имеет то, что m_value используется BinaryFormatter, а объявление структуры совместимо с макетом упакованного Int32. Но этот конструктор этого не сделает, компилятор C# улавливает это на ранней стадии и выдает выделенный код операции CIL для инициализации int.   -  person Hans Passant    schedule 21.03.2018


Ответы (2)


Как он присваивает 6 x?

6, литерал, уже является целым числом. Язык разработан таким образом, что в синтаксисе есть литеральные выражения, которые напрямую интерпретируются компилятором.

Простой 6 является целочисленным литералом и уже соответствует объекту Int32 со значением 6. На самом деле компилятору не нужно вызывать конструктор для литералов, но он может создавать объекты напрямую. В зависимости от типа может быть разный синтаксис для разных литералов. Например, строковый литерал "foo" также заставляет компилятор напрямую создавать строковый объект со значением "foo".

Обратите внимание, что в этом нет ничего особенного для C# и его системы типизации. Таким образом, является ли Int32 типом значения или нет, на самом деле не имеет значения (String даже не является типом значения, а литералы все еще существуют).

person poke    schedule 21.03.2018
comment
Можно добавить один интересный факт: уже соответствует объекту Int32 со значением 6 не совсем верно. В этот момент в памяти нет ни одного объекта или структуры. Внутри фрейма метода ровно 4 байта, в которые 4 байта (со значением 6) будут скопированы из памяти процесса. - person Evgeny Gorbovoy; 27.08.2019

x = 6;

После компиляции становится:

IL_0001: ldc.i4.6     
IL_0002: stloc.0      

Итак, как вы видите, в .NET есть инструкции для создания целочисленных значений из литералов. Это делается под капотом.

ldc.i4.6 создает «6» и помещает его на вершину стека. (это фактически создание целочисленного значения)

stloc.0 копирует значение с вершины стека в переменную x

person Evgeny Gorbovoy    schedule 21.03.2018
comment
спасибо за вывод. означает ли это, что компилятор не использует структуру Int32, когда мы пишем Int32 x = new Int32(); ? - person csharp newbie; 21.03.2018
comment
@csharpnewbie: это скомпилировано в ldc.i4.0 ; stloc.0, так что нет. Вы можете сами проверить такие вещи с помощью LINQPad; у него есть возможность напрямую выводить скомпилированный IL. - person Jeroen Mostert; 21.03.2018
comment
Компилятор @csharpnewbie не использует ничего из Int32 при создании, но после создания это именно структура Int32 - в ней есть методы, поля и т.д. - person Evgeny Gorbovoy; 21.03.2018