[Забавно]Исключения-генерики
От: Красин Россия  
Дата: 25.10.06 03:51
Оценка: 47 (10)
Доброе утро, коллеги!

В .NET есть презабавнейшая вещь, как оказалось. А именно, можно выкидывать не только исключения, но и исключения generic-типа. Типа такого:
public class InvalidOperationException<T> : InvalidOperationException
{
}
...
public class SomeClass
{
   public static void DoSomething()
   {
     ...
     throw new InvalidOperationException<SomeClass>();
   }
}

В общем-то не сильно удивительный результат, т.к. выкидывать исключения можно любого типа-наследника System.Exception. Интересно другое — с появлением генериков C# приобрел возможность во время компиляции различать InvalidOperationException-ы, пришедшие из разных источников. При этом, не потеряна возможность сделать так:
try
{
   SomeClass.DoSomething();
}
catch (InvalidOperationException ex)
{ 
  //Делаем обработку, не зная, что нам кинули что-то более интересное, чем просто InvalidOperationException
}

Однако, в DoSomething возможно идет работа с вещами, которые тоже иногда выкидывают InvalidOperationException. Например, это может быть работа с сокетами, database provider, работа с коллекциями и т.д. Если нам захочется обработать именно то исключение, что возникло непосредственно в DoSomething (например, мы умеем на такой случай запасной вариант сделать то же самое, но медленнее или еще почему), то мы с легкостью можем сделать так:
try
{
   SomeClass.DoSomething();
}
catch (InvalidOperationException<SomeClass> ex)
{
  //Обработка исключения, возникшего непосредственно в DoSomething
}
catch (InvalidOperationException ex)
{
  //Обработка остальных InvalidOperationException-ов
}
catch (Exception ex)
{
  //Обработка всех прочих исключений
}

В общем-то это мы могли делать и без генериков. Действительно, кто мешает определить класс MyInvalidOperationException : InvalidOperationException и ловить его? Никто, кроме лени. Генерики позволяют выкидывать исключения более легковесно с точки зрения структуры программы. Другой положительный(?) момент — при таком подходе человек, читающий код, быстрее сможет понять, какая именно исключительная ситуация сейчас обрабатывается — ведь у типа исключения появился обратный адрес!

Минусы:

А вот еще есть косяки? Насколько можно использовать подобный подход в реальной жизни?
Re: [Забавно]Исключения-генерики
От: Красин Россия  
Дата: 25.10.06 06:16
Оценка:
Что интересно, в Java 1.5 такой трюк не прокатывает. Генерики там существуют только в Compile Time, т.е. в runtime различить уже никак нельзя будет InvalidOperationException<Class1> и InvalidOperationException<Class2>, поэтому в самом языке запрещено делать catch и throws для исключений-генериков. А вот throw делать можно, только везде приписка идет — "можно, но нафиг? поймать-то не сможем."
Re: [Забавно]Исключения-генерики
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 25.10.06 06:25
Оценка: 8 (1) -1
Здравствуйте, Красин, Вы писали:

К>Минусы:

К>[list]
К>
  • такие исключения не очень радостно будут пересекать границы домена, особенно, если на другой стороне нет сборки с SomeClass.
    Сомневался в том, что клиент сможет откомпилироваться без прототипа... Проверил, так и есть — не может. Если было бы иначе, то стоило бы вообще отказаться от данного "преимущества".
    В Java все же данный момент более грамотно сделан: генерация исключения внутри метода декларируется в его заголовке, соответственно клиент четко знает о типе исключения и более того — обязан написать сооотвествующий обработчик.

    К>
  • Привязка к исключению типа класса, в котором оно выброшено сильнее завязывает нас на реализацию. Впрочем, это лечится, если выкидывать исключения, привязанные к типу интерфейсного класса (т.е. того, о ком знает клиент).
    Не совсем так. По уму клиент должен получать только исключения того уровня абстракции, который он понимает при взаимодействии с условным сервером. К примеру, клиент обращается за определенным списком к серверу, сервер читает данный список из файла и возвращает клиенту. В данном примере клиент не должен получать исключения вроде FileNotFoundException и иже с ним — завязанных на внутреннююю реализацию сервера, клиент понятия не имеет, откуда сервер берет список, ему это и не нужно знать. Он должен получать исключения в абстракции понятной в рамках его взаимодействия с сервером.
    Резюме. Грамотно построенная иерархия исключений не "завязывает на реализацию" (c), а именно является органичной структурой самого взаимодействия.

    К>А вот еще есть косяки? Насколько можно использовать подобный подход в реальной жизни?

    Реализация исключений в исполнении Microsoft мне очень не нравится. Надеюсь, в следующем Framework они сделают это по подобию Sun.
    ... << RSDN@Home 1.2.0 alpha rev. 655>>
  • Re[2]: [Забавно]Исключения-генерики
    От: rsn81 Россия http://rsn81.wordpress.com
    Дата: 25.10.06 06:32
    Оценка: +1
    Здравствуйте, Красин, Вы писали:

    К>Что интересно, в Java 1.5 такой трюк не прокатывает. Генерики там существуют только в Compile Time, т.е. в runtime различить уже никак нельзя будет InvalidOperationException<Class1> и InvalidOperationException<Class2>, поэтому в самом языке запрещено делать catch и throws для исключений-генериков. А вот throw делать можно, только везде приписка идет — "можно, но нафиг? поймать-то не сможем."

    Это действительно так. Но, стоит понимать, что в Java исключения жестко встроены в структуру языка — как говорил выше, компилятор заставляет программиста в обязательном порядке уделять исключениям время: декларировать возможные исключения в заголовках методов и перехватывать на стороне клиента. То есть в Java это отлаженный механизм, который, по-крайней мере, по-моему опыту снижает время отладки и количество ошибок, то есть надежность, на этапе эксплуатации программы.

    Это я к тому, что в .NET возможность типизированных исключений пока только красивость, рюшечка, потому что Framework, во-первых, сам по себе наплевательски относится к исключениям, а во-вторых, побуждает и программиста перенимать подобное отношение.

    Разумеется, реализация generic .NET намного более гибкая и красивая, нежели в Java, бесспорно. Но в отношении исключений не стоит сравнивать Java и .NET по этому критерию.
    ... << RSDN@Home 1.2.0 alpha rev. 655>>
    Re[2]: [Забавно]Исключения-генерики
    От: Pavel M. Россия  
    Дата: 25.10.06 08:38
    Оценка:
    Здравствуйте, rsn81, Вы писали:

    R>Здравствуйте, Красин, Вы писали:


    К>>Минусы:

    К>>[list]
    К>>
  • такие исключения не очень радостно будут пересекать границы домена, особенно, если на другой стороне нет сборки с SomeClass.
    R>Сомневался в том, что клиент сможет откомпилироваться без прототипа... Проверил, так и есть — не может. Если было бы иначе, то стоило бы вообще отказаться от данного "преимущества".
    R>В Java все же данный момент более грамотно сделан: генерация исключения внутри метода декларируется в его заголовке, соответственно клиент четко знает о типе исключения и более того — обязан написать сооотвествующий обработчик.

    не шутите так и с толку не сбивайте людей мы делаем так только если наше исключение не наследовано от RuntimeException, иначе пришлось бы писать слишком много обработчиков везде, например для арифметических операций, вдруг вывалится ArithmeticException.



    Java SDK 1.4 API -&gt; RuntimeException


    RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine.

    A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught.

  • --------------------------
    less think — do more
    Re[3]: [Забавно]Исключения-генерики
    От: rsn81 Россия http://rsn81.wordpress.com
    Дата: 25.10.06 08:56
    Оценка:
    Здравствуйте, Pavel M., Вы писали:

    PM>мы делаем так только если наше исключение не наследовано от RuntimeException, иначе пришлось бы писать слишком много обработчиков везде, например для арифметических операций, вдруг вывалится ArithmeticException.

    Собственно, не вижу, где утверждал что-то противоречащее этому.
    ... << RSDN@Home 1.2.0 alpha rev. 655>>
    Re[4]: [Забавно]Исключения-генерики
    От: Pavel M. Россия  
    Дата: 25.10.06 09:20
    Оценка:
    Здравствуйте, rsn81, Вы писали:

    R>Здравствуйте, Pavel M., Вы писали:


    PM>>мы делаем так только если наше исключение не наследовано от RuntimeException, иначе пришлось бы писать слишком много обработчиков везде, например для арифметических операций, вдруг вывалится ArithmeticException.

    R>Собственно, не вижу, где утверждал что-то противоречащее этому.

    в моем посте
    Автор: Pavel M.
    Дата: 25.10.06
    неправильный момент в вашей цитате выделен жирным шрифтом. Никто не обязан RuntimeException и наследников объявлять в заголовке или отлавливать.
    --------------------------
    less think — do more
    Re: [Забавно]Исключения-генерики
    От: Константин Л. Россия  
    Дата: 25.10.06 10:26
    Оценка:
    Здравствуйте, Красин, Вы писали:

    было бы забавно, если бы их не было
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    Estuve en Granada y me acorde' de ti
    Re[5]: [Забавно]Исключения-генерики
    От: rsn81 Россия http://rsn81.wordpress.com
    Дата: 25.10.06 10:30
    Оценка:
    Здравствуйте, Pavel M., Вы писали:

    PM>Никто не обязан RuntimeException и наследников объявлять в заголовке или отлавливать.

    Ок, не скажу, что придрались к частности, скажу: "Поправили — спасибо".
    Речь шла в целом об исключениях Java, сиречь классе Exception, а значит о классе Throwable.
    В курсе, что RuntimeException — всего лишь его наследник Exception?
    ... << RSDN@Home 1.2.0 alpha rev. 655>>
    Re[6]: [Забавно]Исключения-генерики
    От: Pavel M. Россия  
    Дата: 25.10.06 11:35
    Оценка: +1
    Здравствуйте, rsn81, Вы писали:

    R>Здравствуйте, Pavel M., Вы писали:


    PM>>Никто не обязан RuntimeException и наследников объявлять в заголовке или отлавливать.

    R>Ок, не скажу, что придрались к частности, скажу: "Поправили — спасибо".
    R>Речь шла в целом об исключениях Java, сиречь классе Exception, а значит о классе Throwable.
    R>В курсе, что RuntimeException — всего лишь его наследник Exception?

    да, само собой. но по существу, немного другая вещь.
    --------------------------
    less think — do more
    Re[2]: [Забавно]Исключения-генерики
    От: _FRED_ Россия
    Дата: 25.10.06 11:43
    Оценка:
    Здравствуйте, Константин Л., Вы писали:

    КЛ>было бы забавно, если бы их не было


    Кого? Generic-исключений?
    Тогда можно позабовляться над отсутствием generic-аттрибутов
    ... << RSDN@Home 1.2.0 alpha rev. 652>>
    Now playing: «Тихо в лесу…»
    Help will always be given at Hogwarts to those who ask for it.
    Re[3]: [Забавно]Исключения-генерики
    От: nikov США http://www.linkedin.com/in/nikov
    Дата: 25.10.06 12:24
    Оценка: :)
    Здравствуйте, _FRED_, Вы писали:

    _FR>Здравствуйте, Константин Л., Вы писали:


    КЛ>>было бы забавно, если бы их не было


    _FR>Кого? Generic-исключений?

    _FR>Тогда можно позабовляться над отсутствием generic-аттрибутов

    А вот generic-CBO в compile-time есть, а в runtime — отсутствуют.
    Это забавно.

    class CBO<T> : ContextBoundObject { }
    
    class Program
    {
        static void Main()
        {
            new CBO<int>();
        }
    }
    Re[2]: [Забавно]Исключения-генерики
    От: ie Россия http://ziez.blogspot.com/
    Дата: 26.10.06 04:27
    Оценка:
    Здравствуйте, rsn81, Вы писали:

    К>>А вот еще есть косяки? Насколько можно использовать подобный подход в реальной жизни?

    R>Реализация исключений в исполнении Microsoft мне очень не нравится. Надеюсь, в следующем Framework они сделают это по подобию Sun.

    А что именно не нравиться? Можно по пунктам?
    ... << RSDN@Home 1.2.0 alpha rev. 0>>
    Превратим окружающую нас среду в воскресенье.
    Re[4]: [Забавно]Исключения-генерики
    От: Аноним  
    Дата: 26.10.06 06:30
    Оценка:
    N>А вот generic-CBO в compile-time есть, а в runtime — отсутствуют.
    N>Это забавно.

    N>
    N>class CBO<T> : ContextBoundObject { }
    
    N>class Program
    N>{
    N>    static void Main()
    N>    {
    N>        new CBO<int>();
    N>    }
    N>}
    N>



    Причём даже generic функцию нельзя добавить. А с чем связаны такие ограничения и исправлены ли они в VS 2007?
    Re[3]: [Забавно]Исключения-генерики
    От: rsn81 Россия http://rsn81.wordpress.com
    Дата: 26.10.06 09:31
    Оценка:
    Здравствуйте, ie, Вы писали:

    ie>А что именно не нравиться? Можно по пунктам?

    В этом сообщении
    Автор: rsn81
    Дата: 25.10.06
    .
    ... << RSDN@Home 1.2.0 alpha rev. 655>>
    Re[4]: [Забавно]Исключения-генерики
    От: ie Россия http://ziez.blogspot.com/
    Дата: 26.10.06 09:49
    Оценка:
    Здравствуйте, rsn81, Вы писали:

    ie>>А что именно не нравиться? Можно по пунктам?

    R>В этом сообщении
    Автор: rsn81
    Дата: 25.10.06
    .


    Декларация бросаемых исключений... Хмм... Ну вот в J# она тоже есть. Только вот какое отношение это имеет к фрэймворку
    ... << RSDN@Home 1.2.0 alpha rev. 0>>
    Превратим окружающую нас среду в воскресенье.
    Re[2]: [Забавно]Исключения-генерики
    От: AndrewVK Россия http://blogs.rsdn.org/avk
    Дата: 26.10.06 15:37
    Оценка: +6
    Здравствуйте, rsn81, Вы писали:

    R>Реализация исключений в исполнении Microsoft мне очень не нравится. Надеюсь, в следующем Framework они сделают это по подобию Sun.


    Надеюсь что нет.
    ... << RSDN@Home 1.2.0 alpha rev. 642>>
    AVK Blog
    Re[3]: [Забавно]Исключения-генерики
    От: AndrewVK Россия http://blogs.rsdn.org/avk
    Дата: 26.10.06 15:37
    Оценка:
    Здравствуйте, _FRED_, Вы писали:

    _FR>Тогда можно позабовляться над отсутствием generic-аттрибутов


    А чего тут забавляться? Уроды. Мне из-за этого в одном проекте пришлось всякие стратегии придумывать.
    ... << RSDN@Home 1.2.0 alpha rev. 642>>
    AVK Blog
    Re[5]: [Забавно]Исключения-генерики
    От: AndrewVK Россия http://blogs.rsdn.org/avk
    Дата: 26.10.06 15:37
    Оценка:
    Здравствуйте, <Аноним>, Вы писали:

    А>исправлены ли они в VS 2007?


    Нет конечно.
    ... << RSDN@Home 1.2.0 alpha rev. 642>>
    AVK Blog
    Re[3]: [Забавно]Исключения-генерики
    От: rsn81 Россия http://rsn81.wordpress.com
    Дата: 27.10.06 04:03
    Оценка:
    Здравствуйте, AndrewVK, Вы писали:

    AVK>Надеюсь что нет.

    Разумеется, работы прибавится, надежность программ так просто не дается.
    ... << RSDN@Home 1.2.0 alpha rev. 655>>
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.