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

    +133

    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
    abstract class A { }
    
    abstract class B
    {
         void CallValidate(A objA)
         {
              MethodInfo info = base.GetType().GetMethod("Validate", new[] { objA.GetType() });
    
              if (info == null)
              {
                   throw new ApplicationException("The method 'Validate' with parameter type '" + objA.GetType() + "' is not implemented.");
              }
    
              info.Invoke(this, new object[] { objA });
         }
    }

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

    Запостил: Guid, 02 Апреля 2013

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

    • zogчем?
      Ответить
      • "Зачем?" - не правильный вопрос :) "Зачем делать это нужно было делать так?" :)
        Ответить
    • Какой класс базовый у класса Б?
      Ответить
      • "Метод CallValidate базового класса" - хотел сказать сказать: "Метод CallValidate абстрактного класса B". Вообще, B - это некий абстрактный "валидатор" чего-то там. Еще раз пересмотрел код, оказалось все хуже. Вариант использования предполагался такой:

        abstract class A { ... }
        class A1 : A { ... }
        class A2 : A { ... }
        class A3 : A { ... }

        ...

        abstract class B
        {
        void CallValidate(A objA) { ... }

        void Validate(A1 a) { ... }
        void Validate(A2 a) { ... }
        }

        ...

        B validator;
        validator.CallValidate(new A3()); // бросит исключение, т.к. в B не определен метод "void Validate(A3 a) { ... }"
        Ответить
        • B validator;
          validator.CallValidate(new A3()); // бросит исключение, т.к. в B не определен метод "void Validate(A3 a) { ... }"


          Это как это вы так хитро инстанцировали абстрактный класс?
          Ответить
          • Это псевдокод, который демонстрирует сценарий воспроизведения ошибки, не более того.
            Ответить
    • как говорится "гибкий клиент")))
      Ответить
    • Мне кажется, лучше сделать интерфейс IValidator<T> из одного метода, а в классе B сделать dictionary от типов аргументов к валидаторам. И метод типа Register(T, IValidator<T>).

      Или даже проще - передавать аргументом делегата и прямо при вызове Register подсовывать ему лямбду, если в .NET делегаты могут быть дженериками.
      Ответить
      • Да просто сделать этот интерфейс, IValidator и проверять можно ли превести ссылку к ссылке типа этого интерфейса.
        И все.
        not implemented exeption там есть.
        Ответить
    • шарпов не знаю, но если бы С++, я бы сказал что кто-то опять объелся паттернов и маструбирует визитором.
      Ответить
      • Нет, кто-то тоскует по привычному жабоскриптику.
        Ответить
        • Почему так решили, можно узнать?
          Ответить
          • Динамический вызов там, где, видимо, можно обойтись введением интерфейса.
            Ответить
            • Тоже заметил, что тут просто через жопу вводится интерфейс.
              Но с яваскриптом не связал.
              Ответить
              • Там же уже есть dynamic?
                Ответить
                • К чему этот вопрос?
                  Ответить
                  • Пардон, надо было вопрос в корне треда задавать. Имею в виду, что на мой достаточно далёкий от дотнета взгляд автор кода пытается переизобрести dynamic.
                    Ответить
                    • Нет, он пытается с помощью асбтрактного класса получить not implemented exeption который означает, что в этом классе не переопределен метод абстрактного класса предка.
                      Смысл говнокода в том, что для таких вещей существует интерфейс.
                      Ответить
    • Ну сделал бы виртуальный метод, который по умолчанию кидает исключение, раз уж так хочется
      Ответить

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