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

    +138

    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
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    private static T GetElementValue<T>(this XmlElement elm, string elementName, T defaultValue = default(T), bool throwIfError = false, bool throwIfMissing = false)
    			where T : IConvertible
    {
    	string val = GetElementValue(elm, elementName);
    	if (string.IsNullOrEmpty(val) == false)
    	{
    		if (typeof(T) == typeof(string))
    		{
    			return (T)(object)val;
    		}
    
    		if (typeof(T) == typeof(bool))
    		{
    			return (T)(object)(val == "1");
    		}
    
    		try
    		{
    			if (typeof(T) == typeof(DateTime))
    			{
    				return (T)(object)DateTime.Parse(val, System.Globalization.CultureInfo.InvariantCulture); ;
    			}
    
    
    			return (T)Convert.ChangeType(val, typeof(T), CultureInfo.InvariantCulture);
    		}
    		catch (Exception exc)
    		{
    			if (throwIfError)
    				throw exc;
    		}
    	}
    	if (throwIfMissing)
    		throw new ArgumentNullException("The parameter '" + elementName + "' is missing");
    
    	return defaultValue;
    }

    Используем Generics по-фэншую!

    Запостил: Eugene, 05 Октября 2012

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

    • дай обезьяне гранату^W генерик
      Ответить
    • > (T)(object)val
      Вопрос к знатокам c#: это обязательно, или можно тупо (T)val, даже если классы не унаследованы друг от друга, а просто имеют общего потомка (к примеру object)?
      Ответить
      • не считаю себя знатоком, но все объекты и так наследуются от object. Поэтому приведение к object сомнительно.
        Ответить
        • Ну вот допустим есть A и B порожденные от object. С++ не даст делать статик\динамик каст A* в B* и наоборот, но даст это делать через промежуточный каст в object*. Вот мне кажется что в c# не так, и каст должен работать напрямую.

          > Поэтому приведение к object сомнительно.
          Я тоже так думаю.
          Ответить
          • > C++
            > object*
            что?
            Ответить
            • class object {
                  // кто сказал, что я не могу назвать класс object? ;)
              };
              
              class A : public object {
              };
              
              class B : public object {
              };
              
              A *a = ...;
              B *b1 = dynamic_cast<B*>(a); // так нельзя
              B *b2 = dynamic_cast<B*>(dynamic_cast<object*>(a)); // а так можно
              Ответить
              • >// а так можно
                но exception
                Ответить
                • > но exception
                  Да почему, либо NULL либо B* (если в a валялся объект класса, порожденного и от A и от B). Третьего не дано. Причем внутренний каст можно даже заменить на static_cast, т.к. каст в сторону предков всегда успешен.
                  Ответить
                  • >порожденного и от A и от B
                    ах, это множественное наследование ...
                    Ответить
              • Я долго думал, что за ключевое крестоблядское слово object, пока не увидел, что что-то родные крестоблядские слова нихуя не подсвечиваются.
                Подсветка Паскалём?
                Ответить
                • > Подсветка Паскалём
                  Зеленые скобки, совпадающие по цвету с комментариями как бы намекают нам об этом...

                  Движок подсветки видимо увидел слова object и class и подумал, что это object pascal.
                  Ответить
                  • >Зеленые скобки
                    >совпадающие по цвету с комментариями
                    Тарасу как раз к лицу.
                    Ответить
          • > С++ не даст делать статик\динамик каст A* в B* и наоборот, но даст это делать через промежуточный каст в object*

            Я нуб. Я слился. Я более не достоин почетного звания крестобляди.

            Конечно же такой динамик каст делать можно, и иногда даже нужно. Главное, чтобы объект был полиморфным - имел хотя бы одну виртуальную функцию, к примеру деструктор.

            http://ideone.com/YDXeNQ

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

            *звук выстрела*
            Ответить
            • Shame on you, даже я знаю, что для dynamic_cast нужен полиморфный объект (т.к. указатель на данные о типах хранится рядышком с таблицей виртуальных функций), хоть крестоблядь из меня примерно такая же, как балерина
              Ответить
              • Про RTT инфу я знал... Но мне почему-то казалось, что кастовать объекты не имеющие прямого отношения друг к другу за 1 каст нельзя. И я даже не удосужился откомпилировать и проверить свой пример, который привел Тарасу двумя постами ниже этого фейла.
                Ответить
                • > кастовать объекты не имеющие прямого отношения друг к другу за 1 каст нельзя
                  Должно быть можно, должен получиться нулевой указатель
                  Ответить
                  • Можно. Вот тут http://www.govnokod.ru/12017#comment157849 я этим воспользовался. Собственно в этот момент я и вспомнил, что когда-то писал обратное.
                    Ответить
      • Рассмотрим случай
        class object {
            // реально для этого объекта шарпик юзает сахарок и мы его не видим ;)
        };
        
        class A :  object {
        };
        
        class B :  object {
        };


        Допустим в T находится A. Очевидно не всегда возможен кастинг
        var a = new A(); var b = (B)a;
        Будет ошибка компиляции.

        Кастинг к object обязателен.
        Ответить
        • Элсо я как-то делал как говнокодер в топе, тк генерики не могут в специализацию или частичную специализацию. Пичаль вообщем.
          Ответить
        • > Будет ошибка компиляции.
          Сам проверял или просто мысли?

          P.S. Пойду на ideone протестирую.
          Ответить
          • > Сам проверял или просто мысли?
            > Элсо я как-то делал как говнокодер в топе
            Ответить
          • Да, действительно ошибка компиляции.
            http://ideone.com/5RgFs
            http://ideone.com/bOrb7
            Ответить
            • Неужели вы решили, что шарпик не может в типизацию времени компиляции? Не все скриптовые языки одинаково без типов.
              Ответить
              • >шарпик не может в типизацию времени компиляции
                Там помимо vara есть еще и dynamic.
                Ответить
    • >T defaultValue = default
      Элсо я вижу майкрософт осилила что-то типа std::default, о котором я говорил.
      Ответить
      • эм
        вообще T foo = default(T) больше похоже на T foo = T(), чем на T foo = default
        Specifies the default value of the type parameter. This will be null for reference types and zero for value types.
        Ответить
        • Ага. Я не крутил, полосу прокрутки. А в экран не влезло (T)
          Ответить
    • лучше XElement. его можно явно кастить к примитивным типам.
      XElement elem = getSomeXElement();
      int i = (int)elem;
      так же с XAttribute
      Ответить
    • на словах это фэн-шуй, а на деле...
      Ответить

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