Си диез / Говнокод #11874 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 Eugene, (Updated )

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

  • > (T)(object)val
    Вопрос к знатокам c#: это обязательно, или можно тупо (T)val, даже если классы не унаследованы друг от друга, а просто имеют общего потомка (к примеру object)?
    Ответить
    • не считаю себя знатоком, но все объекты и так наследуются от object. Поэтому приведение к object сомнительно.
      Ответить
      • Ну вот допустим есть A и B порожденные от object. С++ не даст делать статик\динамик каст A* в B* и наоборот, но даст это делать через промежуточный каст в 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
                Да почему, либо 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 каст нельзя
                Должно быть можно, должен получиться нулевой указатель
                Ответить
    • Рассмотрим случай
      class object {
          // реально для этого объекта шарпик юзает сахарок и мы его не видим ;)
      };
      
      class A :  object {
      };
      
      class B :  object {
      };


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

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

        P.S. Пойду на ideone протестирую.
        Ответить
  • >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
    Ответить

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

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8