1) MSDN: It is good programming style to use the break, continue, and return statement in preference to goto whenever possible. Since the break statement only exits from one level of the loop, a goto may be necessary for exiting a loop from within a deeply nested loop. — Т.е. goto неплохо подходит для выхода сразу из нескольких циклов:
#include <stdio.h>
int main()
{
int i, j;
for ( i = 0; i < 10; i++ )
{
printf_s( "Outer loop executing. i = %d\n", i );
for ( j = 0; j < 2; j++ )
{
printf_s( " Inner loop executing. j = %d\n", j );
if ( i == 3 )
goto stop;
}
}
// This message does not print:
printf_s( "Loop exited. i = %d\n", i );
stop:
printf_s( "Jumped to stop. i = %d\n", i );
}
4) Использование goto в машинно генерируемых кодах (всякого рода анализаторы, парсеры).
5) В C# оператор goto незаменим внутри switch;
6) И девушек обижать нехорошо:
…
И да, я склонен всё же к мнению такому (Джонсон М. Харт. Системное программирование в среде Windows, третье издание — 2005 г.): «Возможно, это дело вкуса, — то ли индивидуального, то ли корпоративного, — но многие программисты никогда не используют оператор goto и избегают употребления оператора break, кроме случаев его совместного использования с операторами switch и иногда — в циклах, а также совместного использования с операторами continue. Те, кто мыслит трезво, не спешат определять свою позицию в этом отношении. Обработчики завершения и исключений могут решать многие из тех задач, для решения которых вам хотелось бы привлечь оператор goto и операторы, снабжённые метками.»
Как-то друг показал программу типа «Ping-pong» (клиент отсылает серверу строку «Ping», сервер должен прислать «Pong»), не помню из какой книги. Мне понравилось то, что занимала она меньше 40 строк. Я пообещал в ответ написать аналогию на C# до 50 строк… В общем, если не считать необрабатываемых исключений — уложился.
Но идейность и мощь Erlang-а очевидна. Вспомнить хотя бы Yams vs Apache.
По-моему, всё, что необходимо для отображения чего хочешь в браузере — CSS, JavaScript, HTML5, Flash, Flex, Silverlight, Java Applets, WPF + ClickOnce — уже придумано. В чём смысл? В создании из браузера комбайна? В облегчении жизни web-разработчикам?
Я, конечно, всеми руками за прогресс и за новые идеи. И очень надеюсь, что Native Client не повторит историю ActiveX. Web всегда пытался абстрагироваться от машинного кода в целях кросплатформенности, не обратный ли процесс мы наблюдаем?
ЗЫ. Хочу, чтобы в мире web был только HTML5, CSS, JavaScript — на клиенте, а всё остальное — на сервере.
Если быть ещё точнее, то типы значений обычно хранятся в стеке логического управляемого потока .NET, который не обязательно однозначно отображается на физический поток операционной системы.
В итоге имеем: объекты типов значений хранятся в стеке управляемого потока среды .NET, за исключением случаев, когда объект типа значения является полем класса или элементом массива. С другой стороны, объекты ссылочного типа всегда размещаются в управляемой куче процесса.
Оператор foreach требует, чтобы объект итераций реазизовывал метод с определённой сигнатурой (контракт), но не требует от этого объекта реализации к.-л. интерфейса (такого, как IEnumerable). Если прочитать определение с вики, то именно такое поведение и считается утиной типизацией.
Процитирую:
>> Утиная типизация — вид динамической типизации, применяемой в некоторых языках программирования, когда границы использования объекта определяются его текущим набором методов и свойств, в противоположность наследованию от определённого класса. То есть считается, что объект реализует интерфейс, если он содержит все методы этого интерфейса, независимо от связей в иерархии наследования и принадлежности к какому-либо конкретному классу.
В нашем случае можно сказать, что оператор foreach считает объект коллекцией, если тот реализует метод GetEnumerator().
1) Да, конечно, имеются ввиду экземпляры объектов ссылочного типа. Другое дело, что опускаю эти «подробности» не один я.
2) Тут можно немного пофилософствовать на тему того, что массивы в платформе .NET Framework реализуются как экземпляры класса System.Array, но если рассматривать массив как структуру данных, то вы правы. Массив — ссылочный тип, следовательно, память для него распределяется в куче.
3) А можно поподробнее?
Объединяющая мысль статьи — в C# есть особенности/возможности, о которых вы можете не знать/догадываться. Да прибудет с вами знание этой статьи!
Наверное, название не совсем точно отображает суть. Скорее, «интересные моменты» или «некоторые моменты». Не суть. Первая «проба пера» всё же. Буду совершенствоваться.
У меня не было цели написать что-то из ряда вон выходящего. Всё мною описанное прямым или косвенным образом следует из спецификации языка, потому что по-другому и быть не может. Ничего не имею против, если кто-то всё это знает, а многие знают и больше. Но многие все учатся, и, надеюсь, я помог прояснить им некоторые моменты, дать небольшие рекомендации, конспективно отображая суть проблемы и её решение.
Мне тоже кажется, что ребята из Microsoft завышают расценки — в 20 раз, в 4 раза. Однако часть проблемы в том, что операции упаковки-распаковки в некотором смысле «парные» — если есть упаковка, значит где-то понадобится и распаковка (не факт, конечно). Второе — это неявное создание копии объекта, что тоже нужно держать в уме. Всё это сочетание всё же достаточно существенно снижает производительность, чтобы сделать выбор, например, в сторону обобщений вместо object или dynamic.
Не думаю, что вселенная взорвётся от того, что где-то в коде произойдёт десяток упаковок-распаковок. Но на коллекциях объектов, при массовых «перепаковках» всё же стоит задуматься о производительности.
Цит. (смысловой перевод): упаковка и распаковка — дорогие операции. При упаковке типа значения должен быть создан новый объект. Такая операция может занять до 20 раз больше времени, чем присваивание. При распаковке операция приведения может занять в 4 раза больше времени, чем нужно для присваивания (а распаковка, как известно, всегда сопровождается явным приведением).
1) MSDN: It is good programming style to use the break, continue, and return statement in preference to goto whenever possible. Since the break statement only exits from one level of the loop, a goto may be necessary for exiting a loop from within a deeply nested loop. — Т.е. goto неплохо подходит для выхода сразу из нескольких циклов:
2) Финализация при помощи goto — а он быстро работает, и SEH не всегда помогает:
3) Поддержание принципа «один вход — один выход» при помощи goto:
4) Использование goto в машинно генерируемых кодах (всякого рода анализаторы, парсеры).
5) В C# оператор goto незаменим внутри switch;
6) И девушек обижать нехорошо:
…
И да, я склонен всё же к мнению такому (Джонсон М. Харт. Системное программирование в среде Windows, третье издание — 2005 г.): «Возможно, это дело вкуса, — то ли индивидуального, то ли корпоративного, — но многие программисты никогда не используют оператор goto и избегают употребления оператора break, кроме случаев его совместного использования с операторами switch и иногда — в циклах, а также совместного использования с операторами continue. Те, кто мыслит трезво, не спешат определять свою позицию в этом отношении. Обработчики завершения и исключений могут решать многие из тех задач, для решения которых вам хотелось бы привлечь оператор goto и операторы, снабжённые метками.»
Но идейность и мощь Erlang-а очевидна. Вспомнить хотя бы Yams vs Apache.
псевдоним = второе имя,
синоним = слово, близкое по значению.
Что логичнее?
Я, конечно, всеми руками за прогресс и за новые идеи. И очень надеюсь, что Native Client не повторит историю ActiveX. Web всегда пытался абстрагироваться от машинного кода в целях кросплатформенности, не обратный ли процесс мы наблюдаем?
ЗЫ. Хочу, чтобы в мире web был только HTML5, CSS, JavaScript — на клиенте, а всё остальное — на сервере.
В итоге имеем: объекты типов значений хранятся в стеке управляемого потока среды .NET, за исключением случаев, когда объект типа значения является полем класса или элементом массива. С другой стороны, объекты ссылочного типа всегда размещаются в управляемой куче процесса.
p.s. Язык C++/CLI позволяет создать массив значений в стеке.
Процитирую:
>> Утиная типизация — вид динамической типизации, применяемой в некоторых языках программирования, когда границы использования объекта определяются его текущим набором методов и свойств, в противоположность наследованию от определённого класса. То есть считается, что объект реализует интерфейс, если он содержит все методы этого интерфейса, независимо от связей в иерархии наследования и принадлежности к какому-либо конкретному классу.
В нашем случае можно сказать, что оператор foreach считает объект коллекцией, если тот реализует метод GetEnumerator().
2) Тут можно немного пофилософствовать на тему того, что массивы в платформе .NET Framework реализуются как экземпляры класса System.Array, но если рассматривать массив как структуру данных, то вы правы. Массив — ссылочный тип, следовательно, память для него распределяется в куче.
3) А можно поподробнее?
Объединяющая мысль статьи — в C# есть особенности/возможности, о которых вы можете не знать/догадываться. Да прибудет с вами знание этой статьи!
многиевсе учатся, и, надеюсь, я помог прояснить им некоторые моменты, дать небольшие рекомендации, конспективно отображая суть проблемы и её решение.Не думаю, что вселенная взорвётся от того, что где-то в коде произойдёт десяток упаковок-распаковок. Но на коллекциях объектов, при массовых «перепаковках» всё же стоит задуматься о производительности.
Цит. (смысловой перевод): упаковка и распаковка — дорогие операции. При упаковке типа значения должен быть создан новый объект. Такая операция может занять до 20 раз больше времени, чем присваивание. При распаковке операция приведения может занять в 4 раза больше времени, чем нужно для присваивания (а распаковка, как известно, всегда сопровождается явным приведением).