1. C# / Говнокод #5071

    +124

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    /// <summary>
            /// Return "Yes" for true and "No" for false
            /// </summary>
            public static string GetYesNoString(this bool val) 
            {
                return val ? "Yes" : "No";
            }
    
            /// <summary>
            /// Return "N/A" if no value, "Yes" for true and "No" for false
            /// </summary>
            public static string GetYesNoString(this object val)
            {            
                if(val is bool)
                    return ((bool)val).GetYesNoString();
    
                return "N/A";
            }

    Extension of the object class :) Very stupid because it make sense only for bool type, but it can be selected for every type in intellisense :)

    Запостил: bugotrep, 27 Декабря 2010

    Комментарии (76) RSS

    • Extension methods -- лучший способ превратить код в говно.
      Спасибо, Microsoft!
      Ответить
      • Так это вовсе и не из MS. Это способ создать "переопределённый интерфейс" -- говнокод, исходящий из задач, которые некорректно решаются анализом ООП.
        Ответить
        • Extension methods в спецификацию ввели MS, за что я и говорю им спасибо.

          Существует множество методов обойти ограничения ООП (прототипирование, аспекты, мета программирование), и расширения -- самый топорный из них, превращающий ООП код в кашу.

          Но Microsoft не виновато: у них задача: сделать интструмент, позволяющий быстро и легко делать софт без включения мозгов. И они с ней блестяще справляются.
          Другой вопрос что поддерживать такие макароны почти нереально, но фишка в том, что это-то и не нужно!
          Ответить
          • это фишка, которая скорее вредна, чем удобна. Значит, ею и будут больше вредить
            Ответить
            • зато она позволяет сделать "веб приложение за 15 минут"
              Ответить
              • пхп позволяет сделать веб приложение "хелловорлд" за 3 минуты, включая установку денвера - стоит ли продолжать )
                Ответить
            • Почему же? Объясните дураку. Экстеншены заменяют хелперные классы. Как писать - дело вкуса, соглашений в проекте. Сложно или легко поддерживать - зависит от организации кода в проекте, но не от способа выносить функциональность во внешние классы.
              Ответить
              • тоже самое можно написать теми же хелперными классами. Писанины больше, да, но так яснее
                Ответить
                • Тебе яснее, мне без разницы. Казалось бы, тогда профита нет. А теперь вспомним, зачем сделали экстеншены. Правильно, для LINQ. Можно было бы и без них сделать, но я бы не хотел смотреть на код, состоящий целиком из вызовов методов статических классов. Типа LinqExtensions.Select(LinqExtensions.Whe re(LinqExtensions.... , predicate), selector)
                  Ответить
                  • или можно использовать цепочечные и написать либу по типу жкуери, и было бы
                    Linq.Select("*").From("table").Where("a= 1");
                    Ответить
                    • А где типизация? Что передавать в самый первый Select, когда еще ничего не известно о типе элементов источника данных? Допустим, дженерик-лямбду. Тогда:
                      Linq.Select(new Func<int, string>(input => input.ToString())).From....
                      Потом компилятор должен сравнить, можно ли вытащить из источника данных элементы типа int. Позиция MS в том, что естественный порядок написания запроса - сначала указывать, ОТКУДА выбираем, потом уже ЧТО именно. Что позволяет не писать явно new Func<int, string>(). Тип лямбды будет определен автоматически. Код становится короче и читабельнее.
                      Ответить
          • Насколько я понимаю, эти "расширения" прямой путь борьбы с проблемой именно такой ситуации, когда приходится создавать дополнительные методы, манипулирующие методами уже предоставленного интерфейса. Эта задача не может быть решена прозрачнее и эффективнее, чем прямое добавление подобных методов в класс для конкретного проекта.

            А если кто-то забивает сковородкой гвозди -- то это уже его проблема.
            Ответить
            • видимо, проблема философская, она извечна - сделать язык мощным и гибким, или же не дать прогеру выстрелить себе в ногу
              Ответить
              • Чем бороться с преступностью?
                Игрушечным пистолетом, который не навредит сотруднику полиции, или огнестрельным, из которого он сможет застрелиться?
                :-)
                Ответить
                • в полицию абы кого не берут, аналогия неверна
                  а вот если бы выдавать каждому в целях самообороны - это ближе
                  Ответить
                  • Нет-нет-нет.
                    Очень хорошая аналогия.
                    Программист -- это точно такая же профессия, как и полиция. Программист точно так же работает на благо общества.

                    У полиции свой отбор, у программистов -- свой.
                    Ответить
                    • тогда почему столько гкода?
                      Ответить
                      • Гментов тоже не мало
                        Ответить
                      • Да что гкод. Давайте, когда закон "О полиции" окончательно утвердят, мы вернёмся к этому разговору =)
                        Ответить
                        • мне не актуально, у нас тут давно уже полиция... и не менты, а фараоны )))))
                          Ответить
                    • полицейский аппарат и законодательная система имеют тенденцию создавать атмосферу, порождающую преступность и допустимость преступлений.
                      Ответить
                      • так ведь правильно пишут: "отдел организованной преступности"
                        Ответить
            • >>когда приходится создавать дополнительные методы, манипулирующие методами уже предоставленного интерфейса

              ничего не понял)
              можно пример?
              Ответить
              • Я сам с подобным не сталкивался в жизни, но читал об этом. Примеров жизненных не могу привести.
                Но, теоретически, может случиться так, что есть некоторый класс, который, скажем, предоставляет абстракцию общего назначения, имеет интерфейс, который содержит методы, которые в данной программе часто вызываются в определённой комбинации. (Тут нужно заменить: класс сам об этом не знает (!) это чисто из задачи программы данной получается ... то есть это не та ситуации, когда речь идёт о "стратегиях")

                Например можно нафантазировать абстракцию файла. Его можно открыть, записать в него и закрыть. И скажем, нужно всё время захватывать файл, писать и отпускать. Тогда каждый вызов метода записи в файл в данной, конкретной программе может выглядеть так: obj.open(); obj.put(data); obj.close();

                В C++ такая проблема легко разрешается созданием функции в программе, которая получает ссылку на объект, на котором нужно делать вызовы.
                В языках с объектной парадигмой как основой, а не как инструментом, такая ситуация не разрешается прозрачно, потому что не ясно "куда добавить такой метод", который вообще говоря не добавляет функциональности. Если посмотреть внимательно на эту ситуацию, то любое её разрешение приведёт к неприятному коду. И вот "расширения" -- это самый простой способ с ними справиться.
                Ответить
                • в C# проблему можно решить точно так же. А можно использовать декоратор.
                  Ответить
                  • Если вам необходим ТОЛЬКО новый интерфейс, тогда там адаптеры, вреперы... Но, что делать, если вы и сам объект этого типа используете? Явно, как данную абстракцию. Тогда там появляются ссылки на разделяемый объект или наследование без всякого расширения функциональности и прочее странные вещи.
                    Можно создавать закрытую статическую функцию класса программы, чтобы она сама её вызывала. Всяко можно... Но всё плохо.
                    Вы попой чуете, что это метод абстракции файла, а пихать приходится чёрти-куда.

                    А вот с расширениями у вас появляется точное место. Этот метод, хоть он левый получается, всё же, принадлежит именно абстракции файла, а не программе или интерфейсу какого-нибудь ещё типа.
                    Ответить
              • ничего не понял)
                можно пример?

                public static class Tools{
                public static void foo(Class target);
                }

                Example:
                Class val = new Class();
                Tools.foo(val);

                When extensions are used, then the code change become to this:
                public static class Tools{
                public static void foo(this Class target);
                }

                Example:
                Class val = new Class();
                val.foo();
                or
                Tools.foo(val);

                The only difference is syntax, and extensions works well with intellisense. You can make your extensions to sealed or primitive classes or make a lot of govnocode. The choice is yours :)
                Ответить
                • >> extensions to sealed or primitive classes
                  правильно. А еще можно рефлексией лазить в приватные свойства.
                  К черту архитектуру)
                  Ответить
                  • При чем тут это? Экстеншены не имеют доступа к private или protected мемберам, следовательно, ничего не нарушают, уж тем более архитектуру
                    Ответить
    • А зачем нужно Yes/No? Мироощущение VB'шника?
      bool b = ...;
      string s = b? Boolean.TrueString : Boolean.FalseString;

      Но если даже и так то
      bool? b = val as bool?;
      return v.HasValue ? v.Value.GetYesNoString() : "n/a";
      Ответить
    • .(Всё ясно.) Спасибо.
      Ответить
      • это -- экстешнен метод
        у всех инстансов этого несчастного класса появляется этот метод GetYesNoString()

        но ведь если это метод инстанса -- туда надо как-то передать ссылку на объект, верно?

        вот в этом случае она и передается (this значит "ссылка на объект")

        и тут Вы спросите: а почему же там bool?

        а хрен его знает, наверное автовраппинг сработает

        кстати в некоторых средах на низком уровне методы инстансов так и работают -- в них передается ссылка на объект
        Ответить
        • Спасибо. :)
          Ответить
        • >кстати в некоторых средах на низком уровне методы инстансов так и работают -- в них передается ссылка на объект
          Знаю не по наслышке. :)
          Ответить
          • Вы пишете CLR?) jvm?
            Ответить
            • Просто компилятор в обычные опкоды процессора с простейшим ооп. Ну это для себя. Баловство. :)
              Ответить
              • а язык какой? Или тоже сами изобрели?
                Ответить
                • Просто пишу идеальный язык под себя. Много фишек из С++ (шаблонов пока нет в С++-понимании :( ), есть сишарповские фишечки, есть фишечки из функциональной парадигмы. Когда-нибудь выложу своё творение на ГК. =)

                  Вообще, если есть желание, Вы можете мне что-нибудь посоветовать, просто рассказать о своём идеальном языке кратко в возможностях. Можно на примере другого языка (методом исключения некоторых функций и добавлением новых (ваших желанных) (Рассказать в стиле, как говорил известный персоонаж Никулина:"Хочу такого коня, только без крыльев.") ). Ну или просто скажите, что-бы Вы хотели там видеть (одну самую любимую фишечку). Или посоветуйте посмотреть в сторону какого-то языка.

                  Может быть я их учту. :)
                  Ответить
                  • я люблю жаву, и мечтаю что бы в ней можно было:
                    1) ловить несколько эксепшенов, например:
                    catch (IOException: FileNotFoundException, SocketException ex) {
                      //тут у меня переменная ex типа IOException
                    }


                    2) что бы было множественное наследование (иногда грустно, когда надо перегрузить один метод и делегировать 48): я вкурсе проблемы ромба, но все таки...

                    3) что бы была препроверка условий на нулл (например @NotNull login и теперь если передать null -- просто не скомпилируется).

                    4) видимость на все подпакеты (виден в этом пакете и всех внутри него)

                    это сходу)) а так -- надо подумать конечно
                    Ответить
                    • 1)>catch (IOException: FileNotFoundException, SocketException ex) {
                      Ммм. Я уже начал делать вот так:
                      catch (IOException: FileNotFoundException)
                      catch (SocketException ex)
                      {
                      ...
                      }
                      Хотя подумаю над вашим предложением...

                      2)>я вкурсе проблемы ромба
                      Множественное будет, но брилиантовую иерархию я собираюсь запретить.

                      3)3е не очень понял. Как это проверка на нуль во время компиляции? Может во время выполнения?

                      4)Поясните. Например, на примере кода.
                      Ответить
                      • >1)Я уже начал делать вот так:
                        catch (IOException: FileNotFoundException)
                        catch (SocketException ex)

                        Правда мне не нравится, что придёться проверять на null exception'ы, что бы определить от какого он произошёл. Если знаете, как разрулить ситуацию - жду совета. :)
                        Ответить
                        • imho переменная должна быть одна, и типа IOException.
                          Ловить пачкой можно только родственные эксепшены, и переменная должна быть типа их общего родителя.

                          Тоесть тут это IO (ибо сокет и FileNotFound -- потомки IO).
                          А вот что бы привести к конкретному типу -- или instanceof или visitor.
                          Ответить
                          • Если ловить по предку одним кэтчом, то к потомку можно привести и потом, если нужно...
                            Ответить
                            • а если их 100500 штук, а я хочу поймать только 2?
                              в этом блоке -- 2
                              в другом -- 2
                              итд
                              Ответить
                      • 3)
                        void setName(@NotNull name); 
                        //somewhere in the code
                        foo.setName(null); //will produce compilation error

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

                        4)
                        например у Вас есть пакет view. А у него два подпакета view.html и view.console.
                        а внутри view.html у Вас пакет view.html.jsp (для генерации через JSP) и view.html.xsl (для генерации через xsl). а внутри консоли есть пакет view.console.curses для псевдографики с использованием curses итд.

                        у Вас есть класс, который относится только к view.html (например там что-то для HTML). Какую ему видимость поставить? Если пакетную -- его не увидят во view.html.jsp. Если публичную -- его будет видно везде, где ненужно.

                        Хочется иерархии. Чем ближе к корню, тем более общие классы (от которых все зависят), так что логично сделать видимость на пакет и подпакеты.
                        Ответить
                        • foo.setName(null); //will produce compilation error

                          А какой это профит даёт?
                          Ответить
                          • подсказывает пользователю класса, что эти поля надо обязательно ставить.
                            хотя это и можно описать в javadoc

                            вообще мысль моя сыра: надо обдумать, конечно)))
                            Ответить
                            • Что-то в этом есть... :)
                              Ответить
                              • есть кстати еще штука:
                                для нормальной работы моего класса, у него должно быть установлено N полей. Я не могу пихать их в конструктор по какой-то причине (у меня дураццкая сериализация, требующая parameterless конструктор, я -- бин, который должен иметь сеттеры итд).

                                и я хочу как-то сказать пользователю, что надо вот эти пять полей установить обязательно перед вызовом метода. Можно конечно проверить все самому, и кинуть ObjectNotConfiguredException , но хочется как-то это упростить

                                хотя я не знаю как тут язык поможет
                                Ответить
                                • >Я не могу пихать их в конструктор по какой-то причине (у меня дураццкая сериализация, требующая parameterless конструктор

                                  Я подумаю..., но помоему это противоречит основным концепциям ООП?
                                  Ответить
                            • Для дотнета был такой инструмент FxCop, который потом интегрировали в студию. Он позволяет проверить код на соответствие набору правил. В общем-то одним из них может быть и такое. Пометил свойство или метод атрибутом - правило проверяется. Я правильно понимаю, что @NotNull это аналог атрибута? Если так, то можно и не определять это на уровне языка.
                              Ответить
                              • Я слышал про него: с него видимо слизала идею своих инспекшинов идея.

                                @ -- это атрибут. В C# это было бы <NotNull> кажется
                                Ответить
                    • (1) и (3) вроде будет в Java7 или Java8 (действительно, полезно).

                      (2) -- нафиг. Даже в C++ это больше создаёт проблем (кроме наследования от чисто абстрактных классов, т.е. интерфейсов).

                      (4) -- поздно менять, да и не очень-то нужно.
                      Ответить
                  • Основные особенности "моего" (всё, конечно, придумано до меня) языка (притом что большая часть идей взята из С++ (на данный момент) ):

                    1)Все "переменные" константные по умолчанию, кроме переменных для цикла for.

                    2)Можно добавить var и "переменная" становится переменной)))

                    3)Массивы, встроенные в язык, более функциональны, например всегда знают свою длину и их можно возвращать как результат функции.

                    4)Механизм потоков встроен в язык.

                    5)Каждый поток имеет свою копию переменных, в том числе глобальных.

                    6)Переменные могут стать общими для нескольких потоков, если объявлять их как shared.

                    7)Не знаю, вводить ли volatile (встроенная синхранизация перед обращением, к переменной)?

                    8)Планирую более декларативный for(кроме приплюснутого), чтото типа:
                    for (x to 10)
                    for (y = x downto 0)
                    for (x in list)
                    for (x = 1 when x % 2 == 0 to 10)
                    (реализован пока только приплюснутый).
                    Ответить
                    • 9)Из ООП ещё много не реализовано (насколько будет реализовано - зависит от желания, делаю потихоньку, под удовольствие, в свободное от работы время).

                      Ну это основные планируемые отличия от С++. Возможно дальше придумаю больше, тк в планах "прикрутить" и функциональную парадигму (начало положено). Есть идейки о прикручивании некоторых возможностей из С#.

                      10)Сборщик мусора очень модный в наше время, но мне он что-то не нравится... Хочу иметь возможность использовать паттерн RAII нормально, хочу всегда детерминированное освобождение ресурсов (тк это часто источник ошибок у неопытных людей, пересевших на C#). (Впрочем отсутсвие сборщика - не меньшая причина ошибок...) Вообщем ещё пока не решил насчет сборщика (разве, что его пока нет ни в каком виде). Может есть какие идеи насчёт этого пункта? Может вообще не то и не другое выбрать? В прочем мне ничего не приходит в голову - чем это можно заменить...

                      Вообщем, что думаете насчёт этих пунктов? Конечно, понятно, что ничего выдающегося, но все же...

                      Может я делаю велосипед? Есть язык с похожими идеями?

                      Ах да. У него нет названия, пока. Ничего не приходит в голову... G# или G++ - как то банально... Так что можите предлагать. Я подумаю. Быть может, именно Ваше название станет во главе языка. :)
                      Ответить
                      • Гляньте это http://rsdn.ru/article/dotnet/ElaDevelopment.xml
                        Имхо, любопытно. Возможно, вы уже видели этот материал; в частности, идея цикла for во многом совпадают.

                        По десятому пункту.
                        Да, RAII - это хорошо. Я пока далёк от создания своего языка, но думал об этом. Знаю, что в OS Singularity можно использовать разные сборщики мусора. Отталкиваясь от этой идеи, можно попробовать сделать разные GC для разных стратегий приложения, а также чтобы часть программы (модуль или нечто такое) могла работать без GC - тут уже можно реализовать RAII.
                        Ответить
                        • >for (x = 1 when x % 2 == 0 to 10)
                          Вот этот цикл из Ela и взял.
                          Ответить
                        • >for (x to 10)
                          >for (y = x downto 0)
                          Правда ещё думаю над их другой формой записи:
                          for (x -> 10)
                          for (y = x <- 0)

                          Может быть только один из этих 2х оставлю, а именно for (x -> 10), Тоесть стремиться будет лишь к определённому числу (неважно больше оно или меньше).
                          Ответить
                          • >стремиться будет лишь к определённому числу (неважно больше оно или меньше).

                            Это конечно источник неоднозначностей, поэтому видимо будет 2 формы
                            >to
                            и
                            >downto
                            ,а не одна.
                            Ответить
                        • >а также чтобы часть программы (модуль или нечто такое) могли использовать разные сборщики мусора

                          Это источник ошибок, боюсь... Был код с delete, потом решили, что в модуле будет использоваться сборщик, через какое-то время появились без delete'ов части модуля, но снова решили выпилить сборщик мусора... Вот тут придётся дописывать delete'ы... А если забыли, то фейл... Так и будет память утекать.

                          Я думаю завести 2 вида указателей - обычные и со сборкой мусора, но правда это что-то очень похоже на С++\cli...
                          Ответить
                        • в сан jvm можно выбирать из нескольких гц)
                          и даже кажется их настраивать
                          Ответить
                        • Спасибо за статью, интересная!

                          Показалось, что идеи во многом совпадают с Common Lisp; в чем автор, впрочем, косвенно признается.
                          Ответить
                    • 8) http://www.gigamonkeys.com/book/loop-for-black-belts.html
                      Ответить
                  • >Ну или просто скажите, что-бы Вы хотели там видеть (одну самую любимую фишечку).

                    хочу Template Haskell c Dependent-types (хотя бы), а в идеале - все грани лямбда-куба. мммм.. вот этим я бы обмазался
                    Ответить
                  • так что насчет λ2 + λP ?
                    Ответить
                    • Подумаю. Пока ещё с этим нужно разобраться. :-[

                      Я начинал с императива. Теперь в сторону функциональности развиваюсь.
                      Ответить
                      • если уже движение пошло, тогда зачем распыляться?

                        и еще: описано столько тонн сахара, но ни слова о каком-либо средстве для пидорашения AST. весь сахарок сразу в грамматике?
                        Ответить
                        • >пидорашения AST
                          Поясните пожалуйста.
                          Ответить
                          • т.е. средства метапрограммирования, (квазицитирование, гигиена)
                            Ответить
                            • Планирую, но пока не знаю что это будет...

                              Пожалуй это самая интересная часть в языке. :)
                              Ответить
                        • Да. Пишу язык не табличным методом, а через грамматики, если в об этом.
                          Ответить
                        • >тогда зачем распыляться?
                          Если вы о моих распросах на говнокоде, то я не буду против, что-бы в моём языке что-то поменялось. Концепция ведь пока не законченная. Это лишь исследование возможных направлений. Проба пера.
                          Хоть я сейчас уже реализую в таком виде, но возможно дальше абсолютно всё поменяется.

                          Сколько раз уничтожал свой роман "Война и Мир" Лев Николаевич Толстой, прежде чем у него получилась конфетка?
                          Пока у меня не получится конфетка - я своё творение буду безжалостно уничтожать.
                          Ответить
                          • он не с "мама мыла раму" ведь начал?
                            здесь получаются бессмысленные обходные маневры в тылу врага
                            Ответить
                            • :)
                              Набью немного шишек. Это дело житейское.
                              Заказчик не ждёт, поэтому пока можно.
                              Ответить

    Добавить комментарий