C# switch
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 16.01.07 10:56
Оценка: -9 :)
Java-пример:
switch(i) {
  case 0:
    action0(); // заметьте, оператор break далее пропущен специально
  case 1:
    action1();  // итого, это действие выполнится при i равном как 1, так и 0
    break;
}
C#-пример (аналог):
switch(i) {
  case 0:
    action0();
    goto case 1; // goto? прикольно! а почему без этого никак? :-)
  case 1:
    action1();
    break;
}
Только один комментарий: это не holywar, просто забавно.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re[3]: C# switch
От: hell citizen Россия  
Дата: 16.01.07 11:26
Оценка: +1 -1
Здравствуйте, rsn81, Вы писали:

R>Почему: прозрели?


Потому что пример написан таким образом, что порядок следования case-ов имеет значение. Я так никогда не писал, не смотря на то, что плюсы это тоже позволяют. Если нужна указанная логика, правильным будет в action1() первой строкой написать вызов action0().
Re[5]: C# switch
От: hell citizen Россия  
Дата: 16.01.07 12:24
Оценка: +2
Здравствуйте, rsn81, Вы писали:

R>Нет, это не будет правильным.

R>Посмотрите внимательно: для 1-цы не нужно выполнять действия 0.

Отличная иллюстрация почему так не надо писать — можно запутаться самому и запутать других людей
Re[5]: C# switch
От: Блудов Павел Россия  
Дата: 17.01.07 09:43
Оценка: +1 :)
Здравствуйте, fmiracle, Вы писали:

F>На самом деле это ключевой момент.

F>Сделано для большей простоты осознания поведения программы. Потому что в большинстве случаев case сопровождается break и отсутствие его в данном конкретном месте может быть запросто незамечено человеком.

Для простоты осознания нужно было дополнить break его собратом continue:
switch(i)
{
  case 0:
    action0();
    continue;
  case 1:
    action1();
    break;
}

То, что сделано с# это просто извращение.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: C# switch
От: SergH Россия  
Дата: 16.01.07 10:58
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Java-пример:
switch(i) {
R>  case 0:
R>    action0(); // заметьте, оператор break далее пропущен специально
R>  case 1:
R>    action1();  // итого, это действие выполнится при i равном как 1, так и 0
R>    break;
R>}
C#-пример (аналог):
switch(i) {
R>  case 0:
R>    action0();
R>    goto case 1; // goto? прикольно! а почему без этого никак? :-)
R>  case 1:
R>    action1();
R>    break;
R>}
Только один комментарий: это не holywar, просто забавно.


А последний break зачем?
Делай что должно, и будь что будет
Re[2]: C# switch
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 16.01.07 11:06
Оценка:
Здравствуйте, SergH, Вы писали:

SH>А последний break зачем?

Гм... даже не знаю, как серьезно ответить... Ну чтобы компилятору сделать приятно.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re: C# switch
От: serg_fork  
Дата: 16.01.07 11:14
Оценка:
Здравствуйте, rsn81, Вы писали:

R>}[/java]C#-пример (аналог):[c#]switch(i) {


Вот бы вам за этот пример руки поотрывать
Re[2]: C# switch
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 16.01.07 11:19
Оценка:
Здравствуйте, serg_fork, Вы писали:

_>Вот бы вам за этот пример руки поотрывать

Почему: прозрели?
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re[3]: C# switch
От: SergH Россия  
Дата: 16.01.07 11:19
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Гм... даже не знаю, как серьезно ответить... Ну чтобы компилятору сделать приятно.


Не, я не то имел ввиду, но я заблуждался

Я предположил, что раз уж в C# не работает переход к следующему case-у без goto, то и break в конце case не нужен. Имхо логично, компилятор вполне в состоянии сам передать управление за пределы switch-а. Оказывается, это не так.
Делай что должно, и будь что будет
Re[3]: C# switch
От: serg_fork  
Дата: 16.01.07 11:28
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Здравствуйте, serg_fork, Вы писали:


_>>Вот бы вам за этот пример руки поотрывать

R>Почему: прозрели?

1. Если вам нужно сделать что-то не зависимо от кейса, то почему бы это не вынести вверх, зачем городить goto?
            action1();
            switch (i)
            {
                case 0:
                    action0();
                    .....
                    break;
                case 1:
                    .....
                    break;
                case n:
            }


2. Если все же это действие выполняеться лишь в нескольких кейсах, то просто завести action2() в котором и реализовать вызов нужных операций.

Возвращаясь к теме — почему в жаве можно а шарпе нельзя — не знаю, но думаю что это неочевидно и не наглядно, можно забыть про break, и такое начнется : ))))
Re: C# switch
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 16.01.07 11:29
Оценка:
C# еще и так умеет...
switch (0) {
    case 0:
        goto case 0;
}
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re[4]: C# switch
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 16.01.07 11:43
Оценка:
Здравствуйте, hell citizen, Вы писали:

HC>Потому что пример написан таким образом, что порядок следования case-ов имеет значение.

Вот именно.
Причем, если уж продолжать мысль: в Java можно делать таким образом переход только последовательно на следующий case, то с помощью goto C# позволяет абсолютно произвольно скакать по блокам case.

HC> Я так никогда не писал, не смотря на то, что плюсы это тоже позволяют.

А я частенько на Java.

HC> Если нужна указанная логика, правильным будет в action1() первой строкой написать вызов action0().

Нет, это не будет правильным.
Посмотрите внимательно: для 1-цы не нужно выполнять действия 0.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re[4]: C# switch
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 16.01.07 11:43
Оценка:
Здравствуйте, serg_fork, Вы писали:

_>1. Если вам нужно сделать что-то не зависимо от кейса, то почему бы это не вынести вверх, зачем городить goto?

Если бы в примере первым поставил case с каким-то действиями 3 и с break-ом в конце, вас бы устроило?

_>2. Если все же это действие выполняеться лишь в нескольких кейсах, то просто завести action2() в котором и реализовать вызов нужных операций.

Обычно это примитивные действия, шкурка выделки не стоит.

_>Возвращаясь к теме — почему в жаве можно а шарпе нельзя — не знаю, но думаю что это неочевидно и не наглядно, можно забыть про break, и такое начнется : ))))

А goto в современных языках вроде давно уже признанный моветон.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re[4]: C# switch
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 16.01.07 12:02
Оценка:
Здравствуйте, serg_fork, Вы писали:

_>думаю что это неочевидно и не наглядно

switch(0) {
    case 0:    // переход к case 1
    case 1:
        break;
}
switch(0) {
  case 0:
        ;
        goto case 1;    // переход к case 1
    case 1:
      break;
}
А вот это наглядно? Я понимаю, что с точки зрения компиляции это абсолютно разные примеры, но просто на глаз — очень не интуитивно.

PS Я не издеваюсь ни над кем... обидчивые вы мои, кто поставил "минусы" даже не аргументировав свою обидку, так как сам работаю на .NET, просто мне показалось забавной эта особенность компилятора.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re[5]: C# switch
От: ДимДимыч Украина http://klug.org.ua
Дата: 16.01.07 12:05
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Причем, если уж продолжать мысль: в Java можно делать таким образом переход только последовательно на следующий case, то с помощью goto C# позволяет абсолютно произвольно скакать по блокам case.


Не хочу начинать СВ, но это не тот случай, когда goto помогает. В этом случае лучше реализовать конечный автомат.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re: C# switch
От: PhantomIvan  
Дата: 16.01.07 12:50
Оценка:
R>Java-пример:
switch(i) {
R>  case 0:
R>    action0(); // заметьте, оператор break далее пропущен специально
R>  case 1:
R>    action1();  // итого, это действие выполнится при i равном как 1, так и 0
R>    break;
R>}
C#-пример (аналог):
switch(i) {
R>  case 0:
R>    action0();
R>    goto case 1; // goto? прикольно! а почему без этого никак? :-)
R>  case 1:
R>    action1();
R>    break;
R>}
Только один комментарий: это не holywar, просто забавно.


нуууу, не знааааююююю

if (_ == 0)
  action0();
action1();

отэто типа имелось в виду?
на самом деле вышеописанная ситуация — явная заплатка на чём-то

да и вообще, жава-шарповские свитчи слабенькие...
я уж молчу, что есть языки без break-ов
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: C# switch
От: Privalov  
Дата: 16.01.07 12:56
Оценка:
Здравствуйте, rsn81, Вы писали:

_>>Возвращаясь к теме — почему в жаве можно а шарпе нельзя — не знаю, но думаю что это неочевидно и не наглядно, можно забыть про break, и такое начнется : ))))

R>А goto в современных языках вроде давно уже признанный моветон.

В принципе, switch — не меньшее зло, чем goto. А тут все сразу.
Re[2]: C# switch
От: Аноним Великобритания  
Дата: 16.01.07 13:56
Оценка:
PhantomIvan wrote:

> отэто типа имелось в виду?

> на самом деле вышеописанная ситуация — явная заплатка на чём-то
Мне это показалось удобным в следующей ситуации:
switch(currentVersion)
{
case 1:
    ...
    upgradeDocumentFromV1toV2();
    ...
case 2:
    ...
    upgradeDocumentFromV2toV3();
    ...
case 3:
....
}


Т.е. очень удобно добавлять в конец switch автоматические апдейты любой версии документа до последний.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: C# switch
От: PhantomIvan  
Дата: 16.01.07 14:44
Оценка:
А>Мне это показалось удобным в следующей ситуации:
А>
А>switch(currentVersion)
А>{
А>case 1:
А>    ...
А>    upgradeDocumentFromV1toV2();
А>    ...
А>case 2:
А>    ...
А>    upgradeDocumentFromV2toV3();
А>    ...
А>case 3:
А>....
А>}
А>


А>Т.е. очень удобно добавлять в конец switch автоматические апдейты любой версии документа до последний.


1. я бы заюзал Version — класс, который в дотнете имеет место быть, и весьма полезен
2. может быть, расширил бы его (включить бы инфу о дате и т.п.)
3. написал бы обобщённый обработчик "поднятия" до текущей версии
4. внутри него, само собой, был бы цикл

короче я думал над подобной мулькой, пока что не написал её, т.к. не нужно пока
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: C# switch
От: Аноним Великобритания  
Дата: 16.01.07 19:44
Оценка:
PhantomIvan wrote:

> А>Т.е. очень удобно добавлять в конец switch автоматические апдейты

> любой версии документа до последний.
>
> 1. я бы заюзал Version — класс, который в дотнете имеет место быть, и
> весьма полезен
> 2. может быть, расширил бы его (включить бы инфу о дате и т.п.)
> 3. написал бы обобщённый обработчик "поднятия" до текущей версии
> 4. внутри него, само собой, был бы цикл
>
> короче я думал над подобной мулькой, пока что не написал её, т.к. не
> нужно пока
Это называется переусложнение. У меня простая ситуация — версия всегда "+1" (а зачем может понадобится больше? при
необходимости даты легко находятся по истории исходников). Добавление апдейта до новой версии заключается в изменении в
исходнике текущей на +1 и добавлении очередного "case".
Мыслить надо проще.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: C# switch
От: fmiracle  
Дата: 16.01.07 21:26
Оценка:
Здравствуйте, rsn81, Вы писали:


R>}А вот это наглядно? Я понимаю, что с точки зрения компиляции это абсолютно разные примеры, но просто на глаз — очень не интуитивно.


Не понял данных примеров. Первй отлично компилится в шарпе.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: C# switch
От: fmiracle  
Дата: 16.01.07 21:26
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Я предположил, что раз уж в C# не работает переход к следующему case-у без goto, то и break в конце case не нужен. Имхо логично, компилятор вполне в состоянии сам передать управление за пределы switch-а. Оказывается, это не так.


На самом деле это ключевой момент.
Компилятор может многое, но при дизайне шарпа сознательно отказались от "проваливания" между ветками case и запретили case (а так же default) без break

Сделано для большей простоты осознания поведения программы. Потому что в большинстве случаев case сопровождается break и отсутствие его в данном конкретном месте может быть запросто незамечено человеком.

То, что туда можно напихать goto, чтобы получить возможности от которых дизайнеры языка сознательно отказывались, да еще и более ненаглядно сдлеать — ничего не значит. При определенном старании можно все что угодно испоганить
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: C# switch
От: PhantomIvan  
Дата: 16.01.07 21:35
Оценка:
А>Это называется переусложнение. У меня простая ситуация — версия всегда "+1" (а зачем может понадобится больше? при

когда будет по 10 изменений формата в месяц, поймёшь (и возникнет проблема глюков в цепочке конвертации — за всем не уследишь)

А>необходимости даты легко находятся по истории исходников). Добавление апдейта до новой версии заключается в изменении в

А>исходнике текущей на +1 и добавлении очередного "case".

см. рефакторинг "замена условных операторов полиморфизмом", его обоснование, и область применения (Фаулера советую)

А>Мыслить надо проще.


но не проще, чем потребуется для решения задач
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: C# switch
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 21.01.07 11:12
Оценка:
Совсем не в контексте тематики раздела, но раз уж шутка не удалась...

Претензии Вирта к нотациям и синтаксису ЯП
Автор(ы): Никлаус Вирт
Дата: 23.05.2006
Уважаемые читатели! Один из наиболее известных, авторитетных и заслуженных деятелей в области программирования профессор Никлаус Вирт опубликовал в январском номере журнал Computer очень интересную, по моему мнению, статью. Я не мог отказать себе в удовольствии пересказать ее, чтобы предложить получившийся текст вашему вниманию.
в том числе содержат и следующее:
1. goto:

Среди многих плохих идей, представленных на доске позора, идея оператора goto подвергалась наибольшей критике. В языках программирования этот оператор является непосредственным двойником машинной инструкции перехода и может использоваться для конструирования условных и повторяющихся операторов. Но он также дает возможность программистам конструировать запутанный или беспорядочный поток выполнения программы, игнорировать какую-либо регулярную структуру. Это затрудняет, если не делает невозможными, структурные рассуждения о таких программах.

Нашими основными средствами для понимания сложных объектов и управления ими являются структура и абстракция. Мы разбиваем чрезмерно сложный объект на части. Спецификация целого основывается на спецификации его частей. Оператор goto стал прототипом плохой идеи языка программирования, поскольку он может разрушить границы между частями и сделать недействительными их спецификации.


Из этого следует, что язык должен допускать, стимулировать и даже навязывать формулирование программ в виде должным образом вложенных структур, в которых свойства целого могут быть выведены из свойств частей. Рассмотрим, например, спецификацию повторения R оператора S. В этом случае S является частью R. Покажем две возможные формы:

R0: while b do S end
R1: repeat S until b

Ключом к надлежащей вложенности является возможность вывода свойств R из свойств S. Например, если условие (утверждение) P остается справедливым (является инвариантом) при выполнении S, то мы заключаем, что P останется инвариантом, когда выполнение S будет повторяться.

Правила Хоара (Sir Charles Antony Richard Hoare) выражают это формально следующим образом:

{P & b} S {P} влечет {P} R0 {P & b}
{P} S {P} влечет {P} R1 {P & b}

Однако если S содержит оператор goto, то по поводу S невозможно сформулировать какое-либо подобное утверждение, и, следовательно, невозможен какой-либо дедуктивный вывод относительно действия R. Это очень значительная потеря. И действительно, практика показывает, что большие программы без goto гораздо проще понимаются, и гораздо проще обеспечить какие-либо гарантии относительно их свойств.

Об операторе goto говорилось и писалось достаточно, чтобы убедить почти каждого, что это основной пример плохой идеи. Тем не менее, создатель языка Pascal (Напомним, что автором языка Pascal является сам Никлаус Вирт. — С. Кузнецов) оставил в языке оператор goto, а также оператор if без закрывающего символа end. Очевидно, ему не хватило смелости нарушить традицию, и он пошел на ошибочные уступки традиционалистам. Но это было в 1968 г. Теперь почти все понимают суть проблемы, за исключением разработчиков позднейших коммерческих языков программирования, таких как C#.

2. switch:

Если некоторое средство представляет собой плохую идею, то средства, построенные поверх его, оказываются еще хуже. Это правило можно продемонстрировать на переключателе, который, по существу, представляет собой массив меток. Например, в предположении наличия меток L1, : L5 объявление переключателя в языке Algol могло бы выглядеть следующим образом:

switch S := L1, L2, if x < 5 then L3 else L4, L5

Тогда несомненно простой оператор goto S[i] является эквивалентным следующему:

if i = 1 then goto L1 else
if i = 2 then goto L2 else
if i = 3 then
if x < 5 then goto L3 else goto L4 else
if i = 4 then goto L5

Если goto стимулирует беспорядок в программировании, то переключатель делает его неизбежным.

В 1965 г. Хоар предложил наиболее подходящую замену переключателя — оператор case. Эта конструкция представляет собой правильную структуру, в которой операторы-компоненты выбираются в соответствии со значением i:

case i of
1: S1 | 2: S2 | ........... | n: Sn
end

Однако разработчики современных языков программирования решили игнорировать это элегантное решение в пользу гибрида переключателя языка Algol и структурного оператора case:

case statement:
switch (i) {
case 1: S1; break;
case 2: S2; break;
: ;
case n: Sn; break; }

Символ break либо обозначает разделитель между последовательными операторами Si, либо действует как goto на конец конструкции переключателя. В первом случае он является избыточным, а во втором — это замаскированный goto. Этот пример происходит из языка C — плохая концепция в плохой нотации.

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.