Почему я не могу получить общее исключение в С#?
Я делал некоторое модульное тестирование кода, которое могло бы вызывать ряд исключений в зависимости от входов. Поэтому я попробовал что-то вроде приведенного ниже кода: (упрощен для примера)
static void Main(string[] args)
{
RunTest<ArgumentException>();
}
static void RunTest<T>() where T : Exception, new()
{
try
{
throw new T();
//throw new ArgumentException(); <-- Doesn't work either
}
catch (T tex)
{
Console.WriteLine("Caught passed in exception type");
}
catch (Exception ex)
{
Console.WriteLine("Caught general exception");
}
Console.Read();
}
Но это всегда будет печатать "Обходное общее исключение", обработчик catch (T tex) никогда не будет работать. Неважно, бросаю ли я T() или явно бросаю ArgumentException(). Есть идеи, почему это так? На самом деле я был удивлен тем, что даже смог использовать T в предложении catch, но так как это не должно работать? Или, по крайней мере, дать предупреждение/ошибку компилятора, в котором говорится, что этот обработчик никогда не будет работать?
Моя среда - это Visual Studio 2008, а 3.5 - целевая структура.
UPDATE: я попробовал это прямо сейчас из командной строки, а затем распечатывает "Попал в тип исключения". Таким образом, похоже, что это ограничено запуском из Visual Studio. Может быть, особенность хостинга Visual Studio?
Ответы
Ответ 1
Необычное поведение здесь...
VS2k8 консольное приложение. Следующее:
try
{
throw new T();
}
catch (T tex)
{
Console.WriteLine("Caught passed in exception type");
}
catch (Exception ex)
{
Console.WriteLine("Caught general exception");
}
приводит к "Пойманное общее исключение" .
Но удалите (бесполезные) переменные из операторов catch:
try
{
throw new T();
}
catch (T)
{
Console.WriteLine("Caught passed in exception type");
}
catch (Exception)
{
Console.WriteLine("Caught general exception");
}
приводит к "Попал в тип исключения" !!!
Обновление
Хехех... Его ошибка: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362422&wa=wsignin1.0
Источник? Вот. Почему поведение блока catch (TException) отличается от отладчика после установки Visual Studio 2008?
Ответ 2
Работает без отладки
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/0b0e5bc9-fab2-45b1-863b-40abae370475
Уродливое обходное решение (вы можете добавить #if DEBUG):
try
{
throw new T();
}
catch (Exception dbgEx)
{
T ex = dbgEx as T;
if (ex != null)
{
Console.WriteLine(ex.Message);
}
}
Ответ 3
Казалось бы, наиболее конкретным типом исключения, когда задан выбор между T и Exception, является исключение, и поэтому вызывается обработчик.
Я просто попробовал это (вы не можете сделать это на С# или VB, но я отредактировал IL) и изменил второе предложение catch, чтобы поймать Object Ex, а не Exception Ex, и в этом случае первый обработчик получил удар.
Edit
Как указывали другие, это больше связано с запуском его в отладчике, чем конкретный тип