Как использовать ключевое слово Java-style throws в C#?
в Java throws
ключевое слово позволяет методу объявить, что он не будет обрабатывать исключение самостоятельно, а скорее бросит его в вызывающий метод.
есть ли подобное ключевое слово / атрибут в C#?
если нет эквивалента, как вы можете достичь того же (или аналогичного) эффекта?
8 ответов:
в Java вы должны либо обработать исключение, либо пометить метод как тот, который может бросить его с помощью
throws
ключевое слово.C# не имеет этого ключевого слова или эквивалентного, как в C#, если вы не обрабатываете исключение, оно будет всплывать, пока не поймано или если не поймано, оно завершит программу.
Если вы хотите справиться с этим, то повторно бросить вы можете сделать следующее:
try { // code that throws an exception } catch(ArgumentNullException ex) { // code that handles the exception throw; }
ОП спрашивает о C# эквивалент Java
throws
п. - неthrow
ключевое слово. Это используется в сигнатурах методов в Java, чтобы указать, что проверенное исключение может быть брошено.в C# нет прямого эквивалента проверенного исключения Java. C# не имеет эквивалентного предложения подписи метода.
// Java - need to have throws clause if IOException not handled public void readFile() throws java.io.IOException { ...not explicitly handling java.io.IOException... }
переводится как
// C# - no equivalent of throws clause exceptions are unchecked public void ReadFile() { ...not explicitly handling System.IO.IOException... }
Да это старый поток, однако я часто нахожу старые потоки, когда я гуглю ответы, поэтому я решил, что добавлю что-то полезное, что я нашел.
Если вы используете Visual Studio 2012 есть встроенный инструмент, который может быть использован для обеспечения уровня IDE "бросает" эквивалент.
Если вы используете комментарии к XML-документации, как упоминалось выше, то вы можете использовать тег для указания типа исключения, вызванного метод или класс, а также информация о том, когда и почему он выбрасывается.
пример:
/// <summary>This method throws an exception.</summary> /// <param name="myPath">A path to a directory that will be zipped.</param> /// <exception cref="IOException">This exception is thrown if the archive already exists</exception> public void FooThrowsAnException (string myPath) { // This will throw an IO exception ZipFile.CreateFromDirectory(myPath); }
вот ответ на аналогичный вопрос, который я просто финансирую bytes.com:
короткий ответ-нет, в C#нет проверенных исключений. Этот дизайнер языка обсуждает это решение в этом интервью:
http://www.artima.com/intv/handcuffs.html
ближайший вы можете получить, чтобы использовать теги в XML документация и распространение документов, созданных NDoc, с помощью вашего код/сборки так что другие люди могут видеть, какие исключения вы бросить (это именно то, что MS делает в документации MSDN). Вы не можете полагаться на компиляторе, чтобы рассказать вам о необработанных исключениях, однако, как вы можете быть использованы в java.
пройдя через большинство ответов здесь, я хотел бы добавить пару мыслей.
полагаться на комментарии XML-документации и ожидать, что другие будут полагаться на это плохой выбор. Большинство кода C#, с которым я столкнулся, не документирует методы полностью и последовательно с комментариями документации XML. И тогда есть большая проблема, что без проверенных исключений в C#, как вы можете документировать все исключения, которые ваш метод бросает для целей вашего пользователя API знаете, как обращаться со всеми ними по отдельности? Помните, что вы знаете только о тех, которые вы бросаете себе с ключевым словом throw в своей реализации. API, которые вы используете в своей реализации метода, также могут создавать исключения, о которых вы не знаете, потому что они могут быть не задокументированы, и вы не обрабатываете их в своей реализации, поэтому они взорвутся перед лицом вызывающего вашего метода. Другими словами, эти комментарии XML-документации не являются заменой проверенных исключения.
Андреас связал интервью с Андерсом Хейлсбергом в ответах здесь о том, почему команда разработчиков C# решила не проверять исключения. Окончательный ответ на первоначальный вопрос скрыт в этом интервью:
программисты защищают свой код, написав try finally везде, поэтому они будут правильно отступать, если произойдет исключение, но они на самом деле не заинтересованы в обработке исключения.
другими словами, никто не должен быть заинтересован в том, какое исключение можно ожидать для конкретного API, поскольку вы всегда будете ловить их всех везде. И если вы хотите действительно заботиться о конкретных исключениях, как их обрабатывать, зависит от вас, а не от кого-то, определяющего сигнатуру метода с чем-то вроде ключевого слова Java throws, заставляя конкретную обработку исключений для пользователя API.
--
лично я разрываюсь здесь. Я согласен с Андерсом, что проверка исключений не решает проблему без добавления новых, разных проблем. Как и в комментариях к XML-документации, я редко вижу код C# со всем, что завернуто в блоки try finally. Мне кажется, что это действительно ваш единственный вариант и что-то, что кажется хорошей практикой.
на самом деле не проверив исключения в C# можно считать хорошей или плохой вещью.
Я сам считаю, что это хорошее решение, так как проверенные исключения предоставить вам следующие проблемы:
- технические исключения, просачивающиеся на уровень бизнеса / домена, потому что вы не можете обрабатывать их должным образом на низком уровне.
- они принадлежат сигнатуре метода, которая не всегда хорошо играет с дизайном API.
из-за что в большинстве больших приложений вы увидите следующий шаблон часто, когда проверенные исключения происходят:
try { // Some Code } catch(SomeException ex){ throw new RuntimeException(ex); }
что по существу означает эмуляцию того, как C#/.NET обрабатывает все исключения.
есть некоторые мимолетные сходства между .Net CodeContract
EnsuresOnThrow<>
и javathrows
дескриптор, в том, что оба могут сигнализировать вызывающему как тип исключения, которое может быть вызвано из функции или метода, хотя есть также основные различия между 2:
EnsuresOnThrow<>
выходит за рамки простого указания, какие исключения могут быть брошены, но также оговаривает условия, при которых они гарантированно будут брошены - это может быть довольно обременительный код в вызываемом методе, если условие исключения не является тривиальным для идентификации. Javathrows
указывает, какие исключения могут быть брошены (т. е. IMO фокус в .Net находится внутри метода, который заключает контракт, чтобы доказатьthrow
, тогда как в Java фокус смещается на вызывающего, чтобы подтвердить возможность исключения).- .Net CC не делает различия между Checked vs Unchecked исключения, которые есть у Java, хотя CC в разделе 2.2.2 руководства упоминается
" используйте исключительные постусловия только для тех исключений, которые вызывающий объект следует ожидать, как часть API"
- в .Net вызывающий может определить, следует ли делать что-либо с исключением (например, отключив контракты). В Java, вызывающий надо что-то делать, даже если он добавляет
throws
для того же исключения на своем взаимодействие.
Вы спрашиваете об этом :
повторное исключение
public void Method() { try { int x = 0; int sum = 100/x; } catch(DivideByZeroException e) { throw; } }
или
static void Main() { string s = null; if (s == null) { throw new ArgumentNullException(); } Console.Write("The string s is null"); // not executed }