|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
Интересует почему статические конструкторы применяются в обратном порядке, а обычные в прямом порядке - от базового к производному (как в джаве, но вроде бы тоже должны быть в обратном порядке). Например, class A { static A { ... "staticA"...} public A { ..."instanceA"...} } ... class B:A { static B { ... "staticB"...} public B { ..."instanceB"...} } ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 14:10 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutа обычные в прямом порядке - от базового к производному С чего бы это вдруг? Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53.
- все тот же вызов от производного к базовому. Просто вызов непараметриризованного конструктора базового класса неявно вставляется в конструктор производного класса первым (а в случае отсутствия такового пришлось бы руками писать base(arglist), и этой путаницы бы не было), поэтому и кажется, что он вызывается раньше. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 14:36 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
Я сейчас проверить не могу - но все-таки выходит так что сперва вызывается конструктор производного класа, а потом базового (не так как в джаве, по вашему)? В общем случае? Но у меня пример когда есть именно конструктор А и В без параметров, которые лиш как маркеры для проверки выводят некую строку. Проверял, работают от сверху вниз, а статические наоборот. И почему кажется что раньше: B b=new B(); выводит -> staticB->staticA->instanceA->instanceB -- если это исключение для чего то разворачивать порядок. А если будут использоватся лиш дефолтные конструкторы то порядок будет обратный? Но проверить не будет возможно, хотя бы так наочно как здесь. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 14:55 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/classes-and-structs/static-constructors Статический конструктор используется для инициализации любых статических данных или для выполнения определенного действия, которое требуется выполнить только один раз. Он вызывается автоматически перед созданием первого экземпляра или ссылкой на какие-либо статические члены. Если из статического конструктора B() ты не обращаешься к классу A, то при Код: c# 1.
сначала вызовется static B(), затем A(), в начале которого вызовется static A() Ключевое тут: не обращаешься к классу A, поэтому без разницы в каком порядке статические конструкторы отработают. Добавь в static B() обращение к чему-нибудь static из A() и static A() отработает раньше. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 15:21 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutB b=new B(); выводит -> staticB->staticA->instanceA->instanceB Порядок вызовов на самом деле такой: staticB->staticA и instanceB->instanceA, но вызов instancA - первый в теле instanceB. А со статиками и так всё понятно: кто первый используется, того статический конструктор первым и вызывается. Если первый используется B , то первым вызывается его статический конструктор, а поскольку B ссылается на А, то вторым вызывается стат. конструктор А. А поскольку стат. мемберы не наследуются, то и вызова стат. конструкторов по иерархии наследования нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 15:23 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
Вы привели ссылку на статические конструкторы - лутче б привели ссылку на стандартные конструкторы - не знал донедавна что они настолько отличаются от явы. Хотя перед этим где то было подчеркнуто, что при явном вызове базового конструктора он в шарпе находится в не тела конкретного конструктора. А что случается при неявном вызове непонятно, как в моем примере. Но здесь важен результат. В моем примере сперва появляется InstanceA, а потом InstanceB. Касательно утверждение что среди статических конструкторов сперва вызывается тот кто первым используется - то в моем примере нету статических полей потому здесь применяется какое то дефолтное правило. Вот никогда не обращал внимание что статические переменные не наследуются - но в примере обьекта производного класа В -- появляются строки которые пишет сперва стат. констр. класа В, а потом А. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 18:38 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutА что случается при неявном вызове непонятно, как в моем примере. Но здесь важен результат. В моем примере сперва появляется InstanceA, а потом InstanceB. Выше уже писали ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 20:16 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
LRstutА что случается при неявном вызове непонятно, как в моем примере. Но здесь важен результат. В моем примере сперва появляется InstanceA, а потом InstanceB. Выше уже писали Выше уже писали Сон Веры ПавловныПорядок вызовов на самом деле такой: staticB->staticA и instanceB->instanceA, но вызов instancA - первый в теле instanceB. А чтобы убедиться воочию, можно использовать инициализацию полей, вот здесь во втором ответе хороший пример https://social.msdn.microsoft.com/Forums/vstudio/en-US/38a49e82-7404-4222-8a67-88ee3973e475/order-of-execution-of-static-constructor-in-case-of-inheritance-in-c?forum=csharpgeneral Before executing its code, instance constructor of B makes a call to the base constructor: - Static constructor of A is called - Instance constructor of A is called To check exactly what the order is, you need to have code executed just before the base constructor is called, i.e. during fields initialization ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 20:21 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
Собственно порядок вызовов мне не важен - хотя теперь интересно а какой он в jаvа - важен кто придет первый к финишу. И кажется в джаве конструктор вызывается в теле конструктора базового класа - а в шарпе - class B:A { public B:base () {...}. Хотя это явный вариант - может в неявном варианте конструктор базового класа получается и в теле производного конструктора. Вообще хотелось бы получить ссылку на официальную документацию о порядке инициализации нестатических контструкторов при наследовании в шарпе. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.08.2017, 21:57 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutВообще хотелось бы получить ссылку на официальную документацию о порядке инициализации нестатических контструкторов при наследовании в шарпе. C# Language Specification \ Classes \ Instance constructors \ Constructor execution - оно? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.08.2017, 01:14 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
LR, ссылка или ресурс несколько сумбурный. Надо чтобы как в джаве было написано - вот сперва конструктор базового класа, а потом класов наследников. Если вы пишите что конструктор вызывается в теле то я так понимаю что в вышеприденом непараметризированом и недефолтном конструкторе производится имплиситное преобразование public В() { Console.Write(); } => public B() { /* base() */ A(); Console.Write();} Ибо в шарпе при прямом вызове конструктора обычно пишут public B: base() // A() {Console.Write ();} В этом случае конструктор получается в не тела, и вызов идет в обратном порядке? Но где прямо об этих двух случаях написано официально. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 13:55 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
LR C# Language Specification \ Classes \ Instance constructors \ Constructor execution - оно?stutLR, ссылка или ресурс несколько сумбурный. Надо чтобы как в джаве было написано - вот сперва конструктор базового класа, а потом класов наследников. Если вы пишите что конструктор вызывается в теле то я так понимаю что в вышеприденом непараметризированом и недефолтном конструкторе производится имплиситное преобразование public В() { Console.Write(); } => public B() { /* base() */ A(); Console.Write();} Ибо в шарпе при прямом вызове конструктора обычно пишут public B: base() // A() {Console.Write ();} В этом случае конструктор получается в не тела, и вызов идет в обратном порядке? Но где прямо об этих двух случаях написано официально. По той же ссылке: 10.10.1 Constructor initializers Visual Studio .NET 2003 All instance constructors (except those for class object) implicitly include an invocation of another instance constructor immediately before the constructor-body. The constructor to implicitly invoke is determined by the constructor-initializer. про статические в 10.11 Те это для суда надо? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 17:55 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
refreg, all other constructors - но не сказано что они есть в иерархии наследования. И вы же сами привели цыцату, что перед телом конструктора, а не в теле. И что значит before body - что логически сперва исполняется код перед телом, а потом собственно сам блок кода конструктора? В яве как раз все в теле конструктора и сперва инициализация старших конструкоров, хотя наверное если вписать super() в конец то будет наоборот. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 18:44 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutrefreg, all other constructors - но не сказано что они есть в иерархии наследования. И вы же сами привели цыцату, что перед телом конструктора, а не в теле. И что значит before body - что логически сперва исполняется код перед телом, а потом собственно сам блок кода конструктора? В яве как раз все в теле конструктора и сперва инициализация старших конструкоров, хотя наверное если вписать super() в конец то будет наоборот. Я ссылку выше дал 20739051 русским по белому расписано как работает. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 19:38 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutrefreg, all other constructors - но не сказано что они есть в иерархии наследования Не all others, a all instance constructors. Если конструктора нет в иерархии наследования, то это может означать только одно - явноя инстанциирование экземпляра другого класса в конструкторе, к рассматриваемому вопросу данный случай не относится. Ну и, наконец, вполне можно убедиться самому. Короткий пример выше я приводил, вот более развернутый. Из IL-кода прекрасно видно, как это происходит (в полном соответствии с документацией, и с тем, что здесь про всё это писали): Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35.
Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 19:57 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutrefreg, all other constructors - но не сказано что они есть в иерархии наследования. И вы же сами привели цыцату, что перед телом конструктора, а не в теле. И что значит before body - что логически сперва исполняется код перед телом, а потом собственно сам блок кода конструктора? В яве как раз все в теле конструктора и сперва инициализация старших конструкоров, хотя наверное если вписать super() в конец то будет наоборот.Вот те еще выдержка из того же раздела: If an instance constructor has no constructor initializer, a constructor initializer of the form base() is implicitly provided. Thus, an instance constructor declaration of the form C(...) {...} is exactly equivalent to C(...): base() {...} Таким образом вызвается тот конструктор, который вызвается, а он перед "телом", вызывает либо то, что прописано (например, там может быть this - не обязательно base) либо base(). Все предельно ясно и точно, никаких прямых и обратных вызововов (я так и не понимаю почему один порядок для тя прямой другой обратный) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 20:18 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stut, Наверное путаница возникла из-за того, что понятие "конструктор" можно трактовать двояко - в узком смысле, лишь как код в c#-методе-"конструкторе" и в широком смысле - создание реального объекта, смотрите к примеру IL-код method C::.ctor, приведенный выше Сном Веры Павловны (здесь 1.инициализация полей, 2.вызов "широкого" конструктора базового класса, 3.выполнение кода "узкого" конструктора). Ну а по той ссылке на спецификацию очень доступно объясняется, в т.ч., почему на 1-м месте инициализация полей. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 21:03 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
LR, вот именно, я как не очень искушенный в практике програмист, по ходу уже перестал понимать что два контструкторы в класе потомке строять один и тот же обьект класа потомка, а не как бы создают два модуля в одном обьекте. Хорошо что джаве статических конструкторов не встречал, хотя может они и есть. Но снова таки: что значит no constructor initializes (я это понимал как дефолтный конструктор). В моем примере дефолт переопределен - public B() {Console.Write("instanceA");}. Инициализация присутсвует. Снова таки было б четко указано про порядок конструкторов с простыми примерами было бы проще. А то уж то очень закручено, с оставшиемися вопросами. Порядок обратный - как бы специально для статиков, но в инстансах -- они имплиситно вызывают базовый конструктор - так напишите на английском со стороны микрософта, с простым примером. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 22:44 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutтак напишите на английском со стороны микрософта, с простым примером. Так вроде ж написано. Допустим есть Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
При создании экземляра Item3 первым отработает конструктор object, потом Item1, потом Item2, потом Item3. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 23:07 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutLR, вот именно, я как не очень искушенный в практике програмист, по ходу уже перестал понимать что два контструкторы в класе потомке строять один и тот же обьект класа потомка, а не как бы создают два модуля в одном обьекте. Хорошо что джаве статических конструкторов не встречал, хотя может они и есть. Но снова таки: что значит no constructor initializes (я это понимал как дефолтный конструктор). В моем примере дефолт переопределен - public B() {Console.Write("instanceA");}. Инициализация присутсвует. Снова таки было б четко указано про порядок конструкторов с простыми примерами было бы проще. А то уж то очень закручено, с оставшиемися вопросами. Порядок обратный - как бы специально для статиков, но в инстансах -- они имплиситно вызывают базовый конструктор - так напишите на английском со стороны микрософта, с простым примером.Какой бардак... ... |
|||
:
Нравится:
Не нравится:
|
|||
26.08.2017, 23:54 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
stutНо снова таки: что значит no constructor initializes (я это понимал как дефолтный конструктор). В моем примере дефолт переопределен - public B() {Console.Write("instanceA");}. Инициализация присутсвует. refregIf an instance constructor has no constructor initializer, a constructor initializer of the form base() is implicitly provided. Thus, an instance constructor declaration of the form C(...) {...} is exactly equivalent to C(...): base() {...} Согласно спецификации может быть два варианта: constructor_initializer : ':' 'base' '(' argument_list? ')' | ':' 'this' '(' argument_list? ')' stut, есть спецификация языка, предлагаю начать с выражения new T(A) - https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#object-creation-expressions и затем уже заканчивать конструкторами - https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#instance-constructors ... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 00:49 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
У меня так получилось: Код: plaintext 1. 2. 3.
Исходник Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 09:25 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
Dima TУ меня так получилось: Все согласно сказанному выше Код: c# 1. 2. 3. 4. 5. 6.
До кучи - https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#static-constructors ... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 11:25 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
LRDima TУ меня так получилось На моей памяти - не поверите, но я трезвый был - человеку удавалось получить инстанс класса Math. Там да, были те еще изввраты с рефлекшеном, но ... это совсем не те практики для нормального программирования. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 11:57 |
|
Порядок инициализации конструкторов в c#
|
|||
---|---|---|---|
#18+
Сон Веры Павловны, наверное это был какой-нить MyTrick.Math (а не System.Math)? Совсем не в тему, прошу прощения, но, глянув исходники Math , озадачился: почему doubleRoundLimit объявлено как static, а maxRoundingDigits - как const? Почему не одинаково? Оно, наверное, и не принципиально, но порождает недопонимание... ... |
|||
:
Нравится:
Не нравится:
|
|||
27.08.2017, 14:49 |
|
|
start [/forum/topic.php?fid=20&fpage=40&tid=1399736]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
42ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
62ms |
get tp. blocked users: |
2ms |
others: | 13ms |
total: | 158ms |
0 / 0 |