Возможный синтаксис для мультитиповых блоков catch в C #? - PullRequest
1 голос
/ 07 октября 2009

Вот два предыдущих вопроса по этой теме:

Я работал сегодня и подумал, что это может быть подходящим синтаксисом, если эта функция будет когда-либо добавлена ​​в язык C #. У кого-нибудь есть мнения по этому поводу?

Тип e должен быть базовым типом или интерфейсом для каждого из перечисленных типов исключений.

Редактировать : В этом примере блок catch обрабатывает либо ArgumentNullException, либо ArgumentOutOfRangeException и помещает экземпляр исключения в переменную типа ArgumentException с именем e. Он не обрабатывает любой другой тип ArgumentException, кроме двух перечисленных. Я думаю, что была некоторая путаница относительно ассоциативности , и as.

Редактировать 2: Если все перечисленные исключения выгружаются в переменную типа e, то код корректно компилируется в MSIL без каких-либо приведений или явных проверок типов, что делает его быстрее (потенциально значительно ) чем текущий синтаксис перехвата ArgumentException, за которым следует throw;, если он не является одним из двух, которые вы намеревались. Проблема становится еще более очевидной, если вы перехватываете Exception и проверяете два возможных типа для обработки, а затем перебрасываете, если это что-то еще.

try
{
}
catch (ArgumentNullException, ArgumentOutOfRangeException as ArgumentException e)
{
}

Ответы [ 6 ]

3 голосов
/ 07 октября 2009

Смотрите это:
Круто или глупо? Catch (исключение [NamingException, CreateException] e)

Мой ответ на этот вопрос заключается в том, что они должны позволять вам «складывать» их, используя блоки:

try
{
}
catch (ArgumentNullException e)
catch (ArgumentOutOfRangeException e)
catch (ArgumentException e)
{

}

Хотя я вижу, что вы идете за и , а не или . Лично я не считаю подход и очень полезным, потому что вы уже ограничены реальным неинтерфейсным типом исключения и двойного наследования нет.

1 голос
/ 08 октября 2009

Включение этой функции планируется для Java 7 со следующим синтаксисом:

try {  
    return klass.newInstance();  
} catch (InstantiationException | IllegalAccessException e) {  
    throw new AssertionError(e);  
}

Редактировать: Я думаю, что статический тип e является наиболее конкретным общим суперклассом из перечисленных исключений. (В Java могут быть выброшены только экземпляры класса java.lang.Throwable, поэтому перехват с помощью общего суперинтерфейса имеет ограниченную полезность, поскольку исключение не может быть переброшено.)

0 голосов
/ 07 октября 2009

Если ArgumentNullException и ArgumentOutOfRangeException имеют разные интерфейсы, будет трудно правильно разыграть;

Например, ArgumentOutOfRangeException имеет свойство ActualValue; если вам придется использовать его, вы получите что-то вроде:


if(e is ArgumentOutOfRangeException)
{
    // use e.ActualValue
}
else
{
    // use e.Data
}
0 голосов
/ 07 октября 2009

Вы уже можете сделать это, просто

 try{}
 catch(Exception e)
 {}

, поскольку все исключения происходят из System.Exception. И вы должны сделать то же самое, что и выше, определить тип исключения в самом блоке catch.

0 голосов
/ 07 октября 2009

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

Это что-то, для чего я бы хотел использовать синтаксис:

try
{
}
wrap (OneException as AnotherException)
catch (HandleableException e)
{
    // Actual handling for some exception types
}

... но опять же, я обнаружил, что делаю это гораздо больше в Java, чем в C #.

Есть другие улучшения, которые намного выше моего списка для C #, чем это:)

0 голосов
/ 07 октября 2009

Это будет работать, только если вы не объявите экземпляр (e). Если вы ссылаетесь на е внутри блока, что это такое?

...