Проверяемые исключения -- почему нет в C#?
От: 0K Ниоткуда  
Дата: 27.07.10 08:59
Оценка: -3
Немного повозившись с явой -- понял чего мне не так не хватало в C# -- проверяемые исключения:

* в описании функции (или метода класса) в явном виде перечисляются все типы исключений, которые она может сгенерировать;

*функция, вызывающая функцию или метод с объявленными исключениями, для каждого из этих исключений обязана либо содержать обработчик, либо, в свою очередь, указывать этот тип как генерируемый ею в своём описании.

* компилятор проверяет наличие обработчика в теле функции или записи исключения в её заголовке; если он обнаруживает возможность возникновения исключения, которое не описано в заголовке функции и не обрабатывается в ней, программа считается некорректной и не компилируется.


В C# есть возможность писать в XML-комментарии исключения, которые метод может выбросить. Но мало кто эту возможность использует, как и вообще пишет комментарии. А вот проверяемые исключения -- это часть языка и их бы использовали все.

Конечно, в Java есть некоторые недостатки -- но их бы можно было не повторять в C#.

Собственно вопрос в том, почему такую полезную вещь как проверяемые исключения не включили в язык?
Re: Проверяемые исключения -- почему нет в C#?
От: Mab Россия http://shade.msu.ru/~mab
Дата: 27.07.10 09:00
Оценка: +1
Здравствуйте, 0K, Вы писали:

Поищите по форуму, обсуждение было уже довольно давно, но с тех пор ничего существенного не поменялось, доводы за и против остались теми же.
Re: Проверяемые исключения -- почему нет в C#?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 27.07.10 09:05
Оценка: 13 (3)
Здравствуйте, 0K, Вы писали:

K>Собственно вопрос в том, почему такую полезную вещь как проверяемые исключения не включили в язык?


Why doesn't C# have checked exceptions?
Re[2]: Проверяемые исключения -- почему нет в C#?
От: Kalina9001  
Дата: 27.07.10 10:13
Оценка:
Mab>Здравствуйте, 0K, Вы писали:

Mab>Поищите по форуму, обсуждение было уже довольно давно, но с тех пор ничего существенного не поменялось, доводы за и против остались теми же.


А по поводу константных обьектов, функций как в плюсах, нет такого обсуждения? Мне так этого в шарпе нехватает. Что то типа того:
        public class Test
        {
            public int Value { get; set; }
            public override string ToString() const
            {
                return Value.ToString();
            }

            public void Func(int a) //Not const
            {
                Value = a;
            }
        }

        public void DoWhatWithTest(Test test)
        {
            int x = test.Value; //Ok
            test.Value = 1; //Ok
            string str = test.ToString(); //OK
            test.Func(2); //OK
        }

        public void DoWhatWithConstTest(const Test test)
        {
            int x = test.Value; //Ok
            test.Value = 1; //not Ok
            string str = test.ToString(); //OK
            test.Func(2); //not OK
        }
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
Re: Проверяемые исключения -- почему нет в C#?
От: k.o. Россия  
Дата: 27.07.10 10:19
Оценка: +1
Здравствуйте, 0K, Вы писали:

0K>Немного повозившись с явой -- понял чего мне не так не хватало в C# -- проверяемые исключения:


0K>Собственно вопрос в том, почему такую полезную вещь как проверяемые исключения не включили в язык?


Должны-ли перечисляться типы возможных исключений для делегатов? Как должен выглядеть аналог вот этого с проверяемыми исключениями? Можешь написать декларации для всех используемых здесь методов и делегатов с проверяемыми исключениями?

/// <exception cref="MyNamespace.MyException">description for error condition.</exception>
public IEnumerable<Target> Bar()
{
    IEnumerable<Source> data = ...;

    return data.Select(this.Foo);
}

/// <exception cref="MyNamespace.MyException">description for error condition.</exception>
private Target Foo(Source s)
{
    ...
}

public IEnumerable<Target> Baz()
{
    IEnumerable<int> data = ...;

    return data.Select(i => new Target(i / 2));
}


А для такого?

public void Run(IEnumerable<Source> source, Action<Source> processor, Func<Exception, bool> handler)
{
    foreach (var item in source)
    {
        try
        {
            processor(item);
        }
        catch (Exception e)
        {
            if (!handler(e))
            {
                throw;
            }
        }
    }
}
Re[3]: Проверяемые исключения -- почему нет в C#?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.07.10 10:51
Оценка: +1
Здравствуйте, Kalina9001, Вы писали:

Mab>>Здравствуйте, 0K, Вы писали:


Mab>>Поищите по форуму, обсуждение было уже довольно давно, но с тех пор ничего существенного не поменялось, доводы за и против остались теми же.


K>А по поводу константных обьектов, функций как в плюсах, нет такого обсуждения? Мне так этого в шарпе нехватает.


Потому что честную константность поддерживать в рантайме ох как тяжело, а если только compile-time, то её легко обмануть.
В C++ даже есть стандартные средства для этого.

Гораздо лучше константности иммутабельность и функциональная чистота.
Re: Проверяемые исключения -- почему нет в C#?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.07.10 10:59
Оценка: +1
Здравствуйте, 0K, Вы писали:

0K>Собственно вопрос в том, почему такую полезную вещь как проверяемые исключения не включили в язык?


1)На больших объемах категорически плохо работает. При изменении спецификации одного метода, вызываемого глубоко внутри, придется править спецификации кучи других методов
2)Проблемы при обобщенном программировании и first-class functions, код не может точно сказать что будет выкидываться из него
3)Отсутствие поддержки рантайма, делать её — получится дорого, а без оной — малоэффективно.

Хотя сама идея в контракте метода задавать выбрасываемые исключения — очень даже ниче, но контроль должен быть не такой как в java.

Сейчас подобные задачи вполне может решать Code Contarcts и Pex.
Re[4]: Проверяемые исключения -- почему нет в C#?
От: Kalina9001  
Дата: 27.07.10 11:04
Оценка:
Здравствуйте, gandjustas, Вы писали:

K>>А по поводу константных обьектов, функций как в плюсах, нет такого обсуждения? Мне так этого в шарпе нехватает.


G>Потому что честную константность поддерживать в рантайме ох как тяжело,

Это понятно и наверное не нужно

G> а если только compile-time, то её легко обмануть.

G>В C++ даже есть стандартные средства для этого.

Это тоже понятно, рефлекшином и себе в ногу выстрелить можно


G>Гораздо лучше константности иммутабельность и функциональная чистота.

Задалбывает прокси городить, а повсеместно иммутабельные обьекты использовать не всегда получается
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
Re[2]: Проверяемые исключения -- почему нет в C#?
От: 0K Ниоткуда  
Дата: 27.07.10 11:14
Оценка:
Здравствуйте, k.o., Вы писали:

KO>Должны-ли перечисляться типы возможных исключений для делегатов?


Нужно подумать несколько дней и проверить разные варианты.

Пока мне видится что делегаты нужно сделать гибкими: можно указывать исключения а можно не указывать (если не указали -- проверять не нужно). Т.е. если в сигнатуре делегата не указаны исключения -- при вызове проверять не нужно. По этому использование делегатов накладывало бы определенные риски (они и сейчас есть, кстати).

KO>Как должен выглядеть аналог вот этого с проверяемыми исключениями?


Сигнатура делегата может совпадать с сигнатурой метода (включая исключения), а может и не содержать исключений (ошибкой не будет, только затруднением отладки).

KO>Можешь написать декларации для всех используемых здесь методов и делегатов с проверяемыми исключениями?


С учетом вышесказанного, думаю, понято. В вашем случае не нужно перечислять исключения в сигнатуре делегатов -- при использовании повышаются риски допущения ошибок, зато код становится более универсальным.
Re[2]: Проверяемые исключения -- почему нет в C#?
От: 0K Ниоткуда  
Дата: 27.07.10 11:22
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>1)На больших объемах категорически плохо работает. При изменении спецификации одного метода, вызываемого глубоко внутри, придется править спецификации кучи других методов


Ну так может лучше изменить код, раз появилась возможность нового исключения? Или лучше пусть потом программа упадет?

Точно так-же при добавлении нового параметра в метод -- если добавили -- все нужно менять. Или использовать переопределение.

G>2)Проблемы при обобщенном программировании и first-class functions, код не может точно сказать что будет выкидываться из него


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

G>3)Отсутствие поддержки рантайма, делать её — получится дорого, а без оной — малоэффективно.


Ну Sun же смогли сделать? Неужели у MS денег не хватит?

G>Сейчас подобные задачи вполне может решать Code Contarcts и Pex.


А Pex разве может?
Re[5]: Проверяемые исключения -- почему нет в C#?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.07.10 11:23
Оценка:
Здравствуйте, Kalina9001, Вы писали:


G>>Гораздо лучше константности иммутабельность и функциональная чистота.

K>Задалбывает прокси городить, а повсеместно иммутабельные обьекты использовать не всегда получается

А и не надо везде, пользуй там где удобно.
Re[3]: Проверяемые исключения -- почему нет в C#?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.07.10 11:36
Оценка: +2
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, gandjustas, Вы писали:


G>>1)На больших объемах категорически плохо работает. При изменении спецификации одного метода, вызываемого глубоко внутри, придется править спецификации кучи других методов


0K>Ну так может лучше изменить код, раз появилась возможность нового исключения? Или лучше пусть потом программа упадет?

То что появилась возможность не означает что появится исключение. С высокой долей вероятности если не поменялись вызовы, то и не поменяется поведение, то есть не появятся новые исключение, но все равно придется перелопатить кучу кода чтобы она собралась.
Это кстати приведет к тому что везде будет try{ /*code*/ } catch(Exception) { /*empty*/} для избежания таких проблем.

0K>Точно так-же при добавлении нового параметра в метод -- если добавили -- все нужно менять. Или использовать переопределение.

Добавление параметра — гораздо более редкая операция, чем изменение внутренного поведения. Тем более даже при добавлении параметра можно оставить вызов без параметра, которые дефолтное значение передает. С исключениями так не выйдет.

G>>2)Проблемы при обобщенном программировании и first-class functions, код не может точно сказать что будет выкидываться из него


0K>Эти риски программист должен учесть самостоятельно. Раз начал использовать те же обобщенные делегат -- помни о рисках. Чем более универсальный код -- тем больше рисков.

А что компилятору делать в данном случае? Просто забивать?
То есть если в обобщенном методе будет использоваться тип, обвешанный спецификациями исключений, то компилятор просто проигнорирует это все?
Полезной такой фичи начинает стремиться к нулю (учитывая Linq).

G>>3)Отсутствие поддержки рантайма, делать её — получится дорого, а без оной — малоэффективно.


0K>Ну Sun же смогли сделать? Неужели у MS денег не хватит?

В рантайме? Точно?

G>>Сейчас подобные задачи вполне может решать Code Contarcts и Pex.


0K>А Pex разве может?

Конечно, он все пути выполенния пытается найти, даже те о которых ты не подозреваешь. И громко ругается на любой эксепшен, который не указан в контракте.
Re[4]: Проверяемые исключения -- почему нет в C#?
От: 0K Ниоткуда  
Дата: 27.07.10 13:07
Оценка:
Здравствуйте, gandjustas, Вы писали:

0K>>Ну так может лучше изменить код, раз появилась возможность нового исключения? Или лучше пусть потом программа упадет?

G>То что появилась возможность не означает что появится исключение.

Не понял. Если оно не появится -- зачем его было добавлять?

G>С высокой долей вероятности если не поменялись вызовы, то и не поменяется поведение, то есть не появятся новые исключение, но


Еще раз. Если поведение не изменилось -- откуда взялось исключение?

G>все равно придется перелопатить кучу кода чтобы она собралась.


Это называется рефакторинг. Здесь главное правильный инструмент -- делается одной кнопкой.

G>>>2)Проблемы при обобщенном программировании и first-class functions, код не может точно сказать что будет выкидываться из него


0K>>Эти риски программист должен учесть самостоятельно. Раз начал использовать те же обобщенные делегат -- помни о рисках. Чем более универсальный код -- тем больше рисков.

G>А что компилятору делать в данном случае? Просто забивать?

Ну если программист дергает делегат Func<int, int> -- то компилятор конечно не сможет проверить что за метод в этом делегате и какие у него исключения определены. Программист должен см об этом думать.

Общая идея такая: чем более универсальный код используете -- тем больше вероятность трудноуловимой ошибки.

G>То есть если в обобщенном методе будет использоваться тип, обвешанный спецификациями исключений, то компилятор просто проигнорирует это все?

G>Полезной такой фичи начинает стремиться к нулю (учитывая Linq).

Вовсе нет.

G>>>3)Отсутствие поддержки рантайма, делать её — получится дорого, а без оной — малоэффективно.

0K>>Ну Sun же смогли сделать? Неужели у MS денег не хватит?
G>В рантайме? Точно?

А зачем обязательно в рантайме?

0K>>А Pex разве может?

G>Конечно, он все пути выполенния пытается найти, даже те о которых ты не подозреваешь. И громко ругается на любой эксепшен, который не указан в контракте.

Так это его вручную нужно вызывать для каждого метода?
Re[5]: Проверяемые исключения -- почему нет в C#?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.07.10 13:18
Оценка: 1 (1)
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, gandjustas, Вы писали:


0K>>>Ну так может лучше изменить код, раз появилась возможность нового исключения? Или лучше пусть потом программа упадет?

G>>То что появилась возможность не означает что появится исключение.
0K>Не понял. Если оно не появится -- зачем его было добавлять?

Оно может появиться, но в написаном коде не появится, потому что код и не поменялся.

G>>С высокой долей вероятности если не поменялись вызовы, то и не поменяется поведение, то есть не появятся новые исключение, но

0K>Еще раз. Если поведение не изменилось -- откуда взялось исключение?
Еще раз, остальной код не изменился, не будет исключения.


G>>все равно придется перелопатить кучу кода чтобы она собралась.

0K>Это называется рефакторинг. Здесь главное правильный инструмент -- делается одной кнопкой.
В любом случае это исключение надо где-то обработать, то есть написать try\catch, а это уже геморрой, а не рефакторинг.

G>>>>2)Проблемы при обобщенном программировании и first-class functions, код не может точно сказать что будет выкидываться из него


0K>>>Эти риски программист должен учесть самостоятельно. Раз начал использовать те же обобщенные делегат -- помни о рисках. Чем более универсальный код -- тем больше рисков.

G>>А что компилятору делать в данном случае? Просто забивать?

0K>Ну если программист дергает делегат Func<int, int> -- то компилятор конечно не сможет проверить что за метод в этом делегате и какие у него исключения определены. Программист должен см об этом думать.

Понятно, 100% слились исключения.

0K>Общая идея такая: чем более универсальный код используете -- тем больше вероятность трудноуловимой ошибки.

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

G>>То есть если в обобщенном методе будет использоваться тип, обвешанный спецификациями исключений, то компилятор просто проигнорирует это все?

G>>Полезной такой фичи начинает стремиться к нулю (учитывая Linq).
0K>Вовсе нет.
Докажи.

G>>>>3)Отсутствие поддержки рантайма, делать её — получится дорого, а без оной — малоэффективно.

0K>>>Ну Sun же смогли сделать? Неужели у MS денег не хватит?
G>>В рантайме? Точно?
0K>А зачем обязательно в рантайме?
Читай что я написал.

0K>>>А Pex разве может?

G>>Конечно, он все пути выполенния пытается найти, даже те о которых ты не подозреваешь. И громко ругается на любой эксепшен, который не указан в контракте.

0K>Так это его вручную нужно вызывать для каждого метода?

Да, ты кстати тоже самое предлагаешь. Потому что аннотации надо протаскивать до самого верхнего вызова, не завернутого в try\catch.
Re: Проверяемые исключения -- почему нет в C#?
От: dsorokin Россия  
Дата: 28.07.10 10:44
Оценка: 31 (3) +2
Здравствуйте, 0K, Вы писали:

0K>Немного повозившись с явой -- понял чего мне не так не хватало в C# -- проверяемые исключения:


0K>Конечно, в Java есть некоторые недостатки -- но их бы можно было не повторять в C#.


0K>Собственно вопрос в том, почему такую полезную вещь как проверяемые исключения не включили в язык?


Почитай Programming in Scala. Там написано, почему в Скале отказались от проверяемых исключений, хотя язык работает поверх JVM. Если кратко, то практика показала, что такие исключения провоцируют писать менее надежный код. Исключения просто давятся где-то по середине, дабы ублажить компилятор.
Re[5]: Проверяемые исключения -- почему нет в C#?
От: Undying Россия  
Дата: 29.07.10 03:16
Оценка: -1
Здравствуйте, 0K, Вы писали:

0K>Общая идея такая: чем более универсальный код используете -- тем больше вероятность трудноуловимой ошибки.


Неправильно, правильно так — чем менее прозрачный код используете — тем больше вероятность трудноуловимой ошибки. Код, который для корректной работы должен знать все исключения вызываемых методов крайне не прозрачен, соответственно самое невинное изменение такого кода может привести к неработоспособности программы в целом.
Re: Проверяемые исключения -- почему нет в C#?
От: MozgC США http://nightcoder.livejournal.com
Дата: 29.07.10 12:48
Оценка: 5 (1) +1 -1
Вот глава из книги Clean Code (c) Robert Martin:

Use Unchecked Exceptions

The debate is over. For years Java programmers have debated over the benefits and liabilities of checked exceptions. When checked exceptions were introduced in the first version of Java, they seemed like a great idea. The signature of every method would list all of the exceptions that it could pass to its caller. Moreover, these exceptions were part of the type of the method. Your code literally wouldn’t compile if the signature didn’t match what your code could do.

At the time, we thought that checked exceptions were a great idea; and yes, they can yield some benefit. However, it is clear now that they aren’t necessary for the production of robust software. C# doesn’t have checked exceptions, and despite valiant attempts, C++ doesn’t either. Neither do Python or Ruby. Yet it is possible to write robust software in all of these languages. Because that is the case, we have to decide—really—whether checked exceptions are worth their price.

What price? The price of checked exceptions is an Open/Closed Principle1 violation. If you throw a checked exception from a method in your code and the catch is three levels above, you must declare that exception in the signature of each method between you and the catch. This means that a change at a low level of the software can force signature changes on many higher levels. The changed modules must be rebuilt and redeployed, even though nothing they care about changed.

Consider the calling hierarchy of a large system. Functions at the top call functions below them, which call more functions below them, ad infinitum. Now let’s say one of the lowest level functions is modified in such a way that it must throw an exception. If that exception is checked, then the function signature must add a throws clause. But this means that every function that calls our modified function must also be modified either to catch the new exception or to append the appropriate throws clause to its signature. Ad infinitum. The net result is a cascade of changes that work their way from the lowest levels of the software to the highest! Encapsulation is broken because all functions in the path of a throw must know about details of that low-level exception. Given that the purpose of exceptions is to allow you to handle errors at a distance, it is a shame that checked exceptions break encapsulation in this way.

Checked exceptions can sometimes be useful if you are writing a critical library: You must catch them. But in general application development the dependency costs outweigh the benefits.

Re[5]: Проверяемые исключения -- почему нет в C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.07.10 18:24
Оценка: +1
Здравствуйте, 0K, Вы писали:


0K>Не понял. Если оно не появится -- зачем его было добавлять?


Разработчики фреймворка, увы, обязаны поддерживать не только те сценарии, которые интересны лично вам, но и все остальные сценарии тоже.
В частности, есть масса сценариев с callback — когда я передаю кому-то некую реализацию, а потом вызываю некий код.
Ну, типа
CollectionHelper.ForEach(action, collection)

Теперь я хочу кидать из моего action некий конкретный exception, скажем, FileNotFoundException. И ловить его, соответственно, за пределами ForEach:
try
{
  CollectionHelper.ForEach(action, collection)
}
catch(FileNotFoundException)
{
 ...
}


И вот тут, если есть checked exceptions, я становлюсь обязан вписать это исключение в сигнатуру ForEach. И в сигнатуру IAction, естественно. А это — чья-то 3rd-party library, и перекомпилировать я её не могу. Тупик.
А как быть разработчикам этой библиотеки? Им придётся вписать throws Exception, что равносильно полному отказу от checked exceptions.
Так что разработчики дотнета пошли нам навстречу и приписали throws Exception ко всем методам.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Проверяемые исключения -- почему нет в C#?
От: _FRED_ Черногория
Дата: 30.07.10 18:50
Оценка:
Здравствуйте, Sinclair, Вы писали:

0K>>Не понял. Если оно не появится -- зачем его было добавлять?


S>И вот тут, если есть checked exceptions, я становлюсь обязан вписать это исключение в сигнатуру ForEach. И в сигнатуру IAction, естественно. А это — чья-то 3rd-party library, и перекомпилировать я её не могу. Тупик.


На этот конктетный случай был сделан TargetInvokationException. в шарпе его конечно анализировать не так удобно (хотя возможно) как в языках с фильтрами, но всё же вполне себе кошерный солюшен и ни разу не тупик. Даже более: даёт в место отлова гарантию, что поймалось именно исключение из колбэка и что FileNotFound сгенерирован именно вашим кодом.
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Проверяемые исключения -- почему нет в C#?
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 31.07.10 08:21
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>На этот конктетный случай был сделан TargetInvokationException. в шарпе его конечно анализировать не так удобно (хотя возможно) как в языках с фильтрами, но всё же вполне себе кошерный солюшен и ни разу не тупик. Даже более: даёт в место отлова гарантию, что поймалось именно исключение из колбэка и что FileNotFound сгенерирован именно вашим кодом.


Это значит, что такое исключение тебе придется обрабатывать прямо по месту вызова метода.

Вот пришло тебе TargetInvokationException и внутри может быть что угодно.

Как ты будешь это обрабатывать ?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.