我有一个在运行时接受随机数据的方法(可能是string
,int
等),然后尝试将此数据添加到随机类型的列表中(例如{{ 1}},List<byte>
等)。
由于这种不可预测的特性,我添加了2个错误处理例程。一个用于捕获List<int>
错误并执行一些特定操作来修复数据。其次,我还为FormatException
添加了一个通用的全部内容,所以如果抛出另一个我没想到的错误,我可以显示详细信息并优雅地退出应用程序。
我遇到的(或者至少对我来说似乎很奇怪)这个奇怪的问题是,每当发出Exception
错误时,我的FormatException
什么也不做,而错误就是被Catch (FormatException ex)
抓住了。因此,应用程序退出而不是能够正确处理错误。
为了帮助隔离这一点,我创建了一个小例子C#WinForms程序来复制问题。
这是主要的表单代码:
Catch (Exception ex)
这是我的2个课程的代码:
private void button1_Click(object sender, EventArgs e)
{
// This works normally
ErrorClass.TestCatchFormatException<string, string>("abc", "def");
// This also works normally
ErrorClass.TestCatchFormatException<int, int>("123", "456");
// This should raise a FormatException error but only Exception catches it???
ErrorClass.TestCatchFormatException<int, string>("abc", "456");
}
甚至更奇怪的是,当我查看InnerException时,catch-all public class DataClass<T, U>
{
public T Data1 { get; set; }
public U Data2 { get; set; }
}
public static class ErrorClass
{
public static void TestCatchFormatException<T, U>(dynamic inputString, dynamic inputString2)
where T : IComparable<T>
where U : IComparable<U>
{
try
{
List<DataClass<T, U>> theList = new List<DataClass<T, U>>();
TypeConverter converter1 = TypeDescriptor.GetConverter(typeof(T));
TypeConverter converter2 = TypeDescriptor.GetConverter(typeof(U));
theList.Add(new DataClass<T, U>
{
Data1 = converter1.ConvertFrom(inputString.ToString()),
Data2 = converter2.ConvertFrom(inputString2.ToString())
});
MessageBox.Show(
"Data1 Value is: " + theList[0].Data1.ToString() + "\n"
+ "Data1 Type is: " + theList[0].Data1.GetType().ToString() + "\n"
+ "Data2 Value is: " + theList[0].Data2.ToString() + "\n"
+ "Data2 Type is: " + theList[0].Data2.GetType().ToString());
}
catch (FormatException ex)
{
// Catches nothing for some reason
MessageBox.Show("Caught FormatException\n\n" + ex.Message + "\n\n" + ex.InnerException);
}
catch (Exception ex)
{
// This catches the error but InnerException says the error is of type FormatException.
// Yet FormatException doesn't catch it???
MessageBox.Show("Caught Exception\n\n" + ex.Message + "\n\n" + ex.InnerException);
}
}
}
生成,它说:
System.FormatException:输入字符串的格式不正确。
因此它将其检测为Exception
错误。但由于某种原因,抓住FormatException
什么都不做,只有FormatException
可以抓住它。
有谁知道我在这里做错了什么?
答案 0 :(得分:3)
您的FormatException
包含在其他Exception
类型中。这就是 .InnerException 属性为FormatException
的原因。尝试在看到包装类型的异常时调用 .GetType ,然后抓住它。
答案 1 :(得分:1)
BaseNumberConverter.ConvertFrom()
在内部调用辅助函数来抛出异常:
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
...
catch (Exception e) {
throw FromStringError(text, e);
}
}
return base.ConvertFrom(context, culture, value);
}
FromStringError
的实施是:
internal virtual Exception FromStringError(string failedText, Exception innerException) {
return new Exception(SR.GetString(SR.ConvertInvalidPrimitive, failedText, TargetType.Name), innerException);
}
因此它会抛出Exception
包裹实际的FormatException
并添加一些其他信息(即它尝试转换的值以及它尝试转换为的类型)。为什么它不会抛出另一个我不知道的FormatException
。
在C#6之前,无法创建基于catch
捕获的InnerException
。您必须抓住Exception
并检查InnerException
类型以便以不同方式处理它。
使用C#6,您可以使用异常过滤器:
catch (Exception ex) when (ex.InnerExcpetion is FormatException)
{
// Catches nothing for some reason
MessageBox.Show("Caught FormatException\n\n" + ex.Message + "\n\n" + ex.InnerException);
}
catch (Exception ex)
{
// This catches the error but InnerException says the error is of type FormatException.
// Yet FormatException doesn't catch it???
MessageBox.Show("Caught Exception\n\n" + ex.Message + "\n\n" + ex.InnerException);
}