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

    +126

    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
    public static bool GetSafeBool(object val, bool defaultVal)
            {
                //TODO: check functionality
                bool result = defaultVal;
                try
                {
                    if (val != null)
                    {
                        string str = val.ToString().Trim();
                        // compare ignore case, for performance
                        result = (0 == string.Compare(str, true.ToString(), true) || str == "1" || str == "-1");
                    }
                }
                catch { }
                return result;
            }

    Продолжая тему расовых индусов...

    Запостил: fade, 27 Сентября 2011

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

    • может я чего-то не понимаю в тонкостях шарпа, но код - хороший.
      со всех сторон.
      Ответить
      • _тонкости_ C#: http://msdn.microsoft.com/en-us/library/58918ffs.aspx
        Ответить
        • и какое отношение typeof имеет к парсингу объекта в boolean?
          если и смотреть - то сюда
          http://msdn.microsoft.com/en-us/library/system.boolean.parse.aspx

          особенно вот:
          ' Cannot parse '0'.
          ' Cannot parse '1'.
          ' Cannot parse '-1'.
          числа парсить оно не умеет, а кому-то было нужно чтоб умел.
          Ответить
          • Например можно так:
            Object i = 0;
            System.Type type = typeof(i);
            if( type.FullName == …
            А что делать с -1, 0, 3, 9, 11,22,- 22 или с другим типом — дело то не хитрое...
            Ответить
            • замечу, что в коде выше есть ровно 1 if - проверка на null.
              это хорошо.

              тут же наверняка придется проверять каждый тип.
              if( type.FullName == "byte")
              if (i=-1)
              ...
              else if( type.FullName == "int")
              if (i=-1)
              ...
              else if( type.FullName == "long")
              if (i=-1)
              ...
              else if( type.FullName == "string")
              if (i="-1")
              ...
              это попахивает http://govnokod.ru/7905,но там такой подход более-менее обоснован
              Ответить
              • В-нулевых: проверка на null, даже не обсуждается,
                она обязательна и очевидна. Не будем беспокоить кэпа, хотя бы в этом посте.
                Во-первых: это сегодня может быть только int, а завтра,
                из-за расположение звёзд, как минимум, уже нужен будет string или ...
                >тут же наверняка придется проверять каждый тип.
                Во-вторых: Разве при приведении типов int,float,double - все нулевые значения - false, а не нулевые - true, нет?
                Empty string- false, ЕМНИП.
                В-третьих: если уж на то пошло, то http://ru.wikipedia.org/wiki/Теория_множеств
                По #7905: а каким value НЕ может быть?
                Просто проверить на принадлежность к множеству, как вариант http://govnokod.ru/7905#comment108428
                P.S. Странно, довольно частая операция и можно было реализовать некое решение,
                например, метод IsValSystemType, а может и есть уже...
                Ответить
                • >Empty string- false, ЕМНИП.
                  согласен. это тут плохо.

                  >Разве при приведении типов int,float,double - все нулевые значения - false, а не нулевые - true, нет?

                  наверняка раз проверки написаны, значит так было нужно.
                  я бы в этой ситуации конечно наваял что-то такое.
                  if (val != null) {
                          string str = val.ToString().Trim();
                          if (0 == string.Compare(str, "true", true) || !"0" .equals(str))
                          return true;
                      }
                  return defaultVal;
                  Ответить
                  • мда. говно написал.
                    if (String.Empty!=s)
                    return (0 == string.Compare(str, "true", true) || !"0" .equals(str))
                    *самофикс
                    Ответить
                    • Думаю так, что без конкретного ТЗ, можно такие обобщённые кучи понакладывать...
                      Ответить
                    • Я почти уверен, что метод был создан для того, чтобы из XML прочитать "сериализованый" boolean. Т.е. естесственно сделан вместо того, чтобы использвать готовый. И, кроме того, сделан хуже, т.как найти все значения, которые будут false - проще (их меньше, и их можно посчитать), чем все, которые true.
                      Но если это был какой-то принципиально новый текстовый формат сериализавии данных (для которого в .NET не нашлось энкодера / декодера), то все равно, нормально было бы:
                      String.IsNullOrEmpty(value) || value == "0";

                      вместо вообще всей этой функции.
                      Ответить
                      • "False"
                        Ответить
                        • А с чего бы это? Ну, только если автор целенаправленно хотел именно такую возможность. ECMA традиционно строку "False" переведет в boolean как true.
                          Ответить
                        • T.e. value == "0" я добавил именно как исключение из традиционного правила конвертации. Т.как традиционно либо пустая строка либо null дадут false. Из примера выше, я так понял, что автор хотел еще и числа записанные в строку тоже конвертировались. Но если мы слазали, что "False" тоже должно быть переведено в false, то тут и до локализации не долго... да и вообще не понятно, где остановиться :) Можно еще и например вопросы с психотеста анализировать и приводить к boolean :)
                          Ответить
                          • В примере выше видно, что автор хотел "true", "True" или "TRUE" переводить в true. Нетрудно догадаться, как у него может записываться false.

                            Кстати, его код работает и если val — булевское.
                            Ответить
                            • Microsoft стандартизировали C# в ECMA.
                              По поводу "true" - нет, если быть дотошным, то у автора получалось сравнивать с Boolean.TrueString, но это мелочи, т.как не понятно действительно ли это было нужно, или это была ошибка. Поэтому я и говорю, что не понятно, где остановиться. Нужно знать зачем автор это делал. Но, в любом случае код плохой, т.как если автор хотел проверить, что значение принадлежит к какому-то множеству, то последовательно сравнивать с каждым членом множества - говнокод (т.как повторение одного и того же). Но еще и кажется, что автор пытался принадлежность к множеству доказать через то, что значение не принадлежит к другому множеству disjoint (к сожалению не знаю, как по-русски) с нужным множеством, которое еще и бесконечно.
                              Ответить
                              • дисс, джоинт - это уже хип-хоп какой-то
                                Ответить
                              • По-русски disjoint:
                                1) разбирать, разрезать на части, расчленять;
                                2) вывихнуть.

                                Есть множество значений значений, соответствующий true, есть множество значений значений, соответствующий false, но есть и множество значений, не соответствующих ни true, ни false. Как реагировать на них, считать их true, false, третьим значением (null) или выбрасывать исключение — это предпочтения автора.

                                Но по крайней мере для булевского значения код ведёт себя ожидаемо.
                                Ответить
                                • Это значения из другой области :)
                                  В теории множеств одно множество disjoint с другим когда известно, что нет ни одного элемента присутствующего в обоих множествах.
                                  Именно по-этому я и говорил про ECMA - для них (в отличие от типичного для Java, например, взгляда на мир :) нет характерно считать что boolean возможны трех видов, ложь, истина и ни то и ни другое.
                                  Ответить
                                  • Но в мире кроме значений, представляющих true и false существуют и другие значения. Как на них реагировать — произвол автора.
                                    Ответить
                                  • > в отличие от типичного для Java, например, взгляда на мир
                                    в ECMAScript есть такие же обёртки для примитивных типов, как и в Java. Там они даже интересней:
                                    Boolean(new Boolean(false)) == true
                                    Ответить
                                • По поводу ожидаемо - как раз таки нет. И тем более нет, если вы больше пишете на JavaScript или C# - там, как раз таки ожидаемо, что "false" строка приведенная к boolean даст true. Т.е. код смешал две разные вещи: сериализацию и приведение типов. Т.е. если вы читаете из какого-то определенного другого формата (например XML) и там исходя из каких-то соображений boolean как-то по-особому записали... ну это как раз пример велосипеда. Если вам нужно перевести строку в boolean - то от того, что было в строке, при условии, что она была не пустой, менее истинной она не станет.
                                  Но тут опять же надо искать автора и узнать зачем он это сделал, потому что результат получился очень странный. Скорее всего, что именно результат не правильный.
                                  Ответить
                                  • "false" — это строка. А false — булевское значение. Что вернёт оригинальная функция при параметре, равном false, и что ваша?
                                    Ответить
                                    • Нет, это в вашем мире так :) Но чтобы много не теоретизировать: авторы языка / стандарта не разделяли вашу позицию, когда описывали тип boolean. С их точки зрения значений которые одновременно не истина и не ложь не существует. Чтобы это можно было применить на практике, необходимо, чтобы одно из множеств {все истинные} и {все ложные} было конечным (в идеале - содержало всего один элемент, но тут, очевидно, не удалось добиться единогласия, и, поэтому null, пустая строка и false взаимозаменимы).

                                      Что до оригинальной функции - повторюсь. Она делает что-то странное. Скорее всего она не должна делать то, что делает, и повторять ее не нужно. И это потому, что в идеале, опять же, множество ложных должно содержать всего один элемент, но если мы туда добавим произвольное количество других элементов, то с каждым добавленым элементом мы так же добавляем исключение из правила, абсолютно безосновательно.

                                      Есть такой похожий boolean со знаком вопроса - вот там может быть не ложь и не истина, а в таком вот - не может.
                                      Ответить
                                      • > значений которые одновременно не истина и не ложь не существует

                                        Как это не существуют? Красный мяч, 5 сентября 1970 года, «Манифест коммунистической партии» — это истина или ложь? Существуют значения и помимо boolean.
                                        Ответить
                                        • Что случилось 5 сентября 1970 года?
                                          Ответить
                                        • Это в вашем мире :) Это не в обиду, просто есть другой подход, с точки зрения этого подхода тип объекта определяется контекстом. Для языка C# (который является контекстом для определения типа в нашем случае) задано, что все, кроме null, false, 0 и пустая строка - истина, остальное - ложь. Если вы переопределили контекст, и, например, записали значение в XML вы должны объявить правила перевода. Для того, чтобы выразить тип, где истина и ложь не включают в себя все возможные объекты в C# существует похожий тип bool?
                                          http://en.csharp-online.net/ECMA-334%3A_14.10.4_The_bool%3F_logical_operators
                                          (практичность и полезнозность этого типа не имеет отношения к обсуждению).
                                          Что делает код который мы обсуждаем: он смешивает правила перевода типов для C# с правилами чтения типа из одного контекста в другой. Этого изначально делать не нужно было. Поэтому я и говорю, что то, что делает функция скорее всего просто не правильно.
                                          Ответить
                                          • Очевидно же, что у автора другой контекст.

                                            Кстати, в третий или четвёртый раз намекаю вам — что сделает ваш код с val равным false?
                                            Ответить
                    • Да, собственно, вот и готовое решение http://msdn.microsoft.com/en-us/library/e2104c2x.aspx
                      Ответить
      • Сомнительно вообще использование object в качестве самопального bool.
        А также значений 1/-1 как истины.
        Ответить
    • Та ну, синтетика какая-то, человек который так пишет не смог бы MSVS проект создать...
      Ответить
      • Ну, возможно, сам автор метода и не создавал его :)
        Я это нашел в классе Utils на полторы тыщи строк приложения, которое уже около года худо-бедно работает в продакшне.
        Ответить
    • Нда, автору надо на пхп программить и подобных, короче на нетипизированных языках, а на C# делать ему неча.
      Ответить
    • показать все, что скрытоvanished
      Ответить

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