我有一个在运行时接受随机数据的方法(它可以是string
,int
等),然后尝试将这些数据添加到随机类型的列表中(例如List<byte>
,List<int>
等)。
由于这种不可预测的性质,我添加了2个错误处理例程。捕获FormatException
错误并执行一些特定操作来修复数据的方法。其次,我还为Exception
添加了一个通用包,因此,如果引发了我不期望的另一个错误,我可以显示详细信息并正常退出应用程序。
我遇到的奇怪问题(或者至少对我来说似乎很奇怪)是,每当抛出FormatException
错误时,我的Catch (FormatException ex)
都不执行任何操作,而是由Catch (Exception ex)
捕获该错误。因此,该应用程序无法正常处理错误,而是退出。
为了帮助隔离此问题,我创建了一个小示例C#WinForms程序来复制该问题。
这是主要的表单代码:
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");
}
这是我的两个类的代码:
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);
}
}
}
甚至更奇怪的是,当我查看InnerException时,生成了所有
Exception
,它说:因此它将其检测为
FormatException
错误。但是由于某种原因,捕获FormatException
不会执行任何操作,只有Exception
可以捕获它。有人知道我在做什么错吗?
最佳答案
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
并添加了一些其他信息(即,它试图转换的值和它试图转换的类型)。为什么它不抛出另一个我不知道的catch
。在C#6之前,无法创建将基于
InnerException
捕获的Exception
。您必须捕获InnerException
并检查ojit_code类型以不同方式处理它。使用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);
}