This question is close to what I want to do,但不完全在那里。
有没有办法简化以下代码?
private bool ValidDirectory(string directory)
{
if (!Directory.Exists(directory))
{
if (MessageBox.Show(directory + " does not exist. Do you wish to create it?", this.Text)
== DialogResult.OK)
{
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (IOException ex)
{
lblBpsError.Text = ex.Message;
}
catch (UnauthorizedAccessException ex)
{
lblBpsError.Text = ex.Message;
}
catch (PathTooLongException ex)
{
lblBpsError.Text = ex.Message;
}
catch (DirectoryNotFoundException ex)
{
lblBpsError.Text = ex.Message;
}
catch (NotSupportedException ex)
{
lblBpsError.Text = ex.Message;
}
}
}
return false;
}
这似乎是浪费,如果我以后想要更改我向用户报告错误的方式,或者我想记录这些错误,或者其他什么,那么我必须更改5个不同的catch块。我是否遗漏了某些内容,或者是否公然反对代码重用?
我只是想(太)懒惰?
答案 0 :(得分:23)
您可以使用:
catch (SystemException ex)
{
if( (ex is IOException)
|| (ex is UnauthorizedAccessException )
// These are redundant
// || (ex is PathTooLongException )
// || (ex is DirectoryNotFoundException )
|| (ex is NotSupportedException )
)
lblBpsError.Text = ex.Message;
else
throw;
}
答案 1 :(得分:8)
如果异常共享一个共同的超类,那么你可以捕获超类。
答案 2 :(得分:3)
是的,你试图变懒,但懒惰是the virtues of a programmer之一,所以这很好。
关于你的问题:我没有办法知道,但有一些解决方法可用:
答案 3 :(得分:2)
这很烦人,其他答案也提出了很好的解决方法(我会使用@ Lotfi)。
但是,考虑到C#的类型安全性,这种行为是必需的。
假设您可以这样做:
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (IOException,
UnauthorizedAccessException,
PathTooLongException,
DirectoryNotFoundException,
NotSupportedException ex)
{
lblBpsError.Text = ex.Message;
}
现在什么类型ex
?他们都有.Message
,因为他们继承了System.Exception
,但是尝试访问他们的其他任何属性,而且您遇到了问题。
答案 4 :(得分:2)
同样重要的是要注意,当捕获多种类型的异常时,它们应该按大多数顺序排列。 Exception将在列表中找到它匹配的第一个并抛出该错误,不会抛出任何其他错误。
答案 5 :(得分:2)
为了完整起见:
在VB中,您可以使用条件异常处理:
Try
…
Catch ex As Exception When TypeOf ex Is MyException OrElse _
TypeOf ex Is AnotherExecption
…
End Try
这样的Catch
块只能输入指定的异常 - 与C#不同。
也许C#的未来版本将提供类似的功能(毕竟,该代码有一个特定的IL指令)。
MSDN: How to: Filter Errors in a Catch Block in Visual Basic
答案 6 :(得分:0)
你可以做到
ex.GetType()
请参阅http://msdn.microsoft.com/en-us/library/system.exception.gettype.aspx
修改
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (Exception ex)
{ switch(ex.GetType())
case .....
case ..........
blBpsError.Text = ex.Message;
}
答案 7 :(得分:0)
您可以捕获基类异常(所有异常都来自SystemException
):
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (SystemException ex)
{
lblBpsError.Text = ex.Message;
}
但是你最终可能会捕捉到你不想捕捉的异常。
答案 8 :(得分:0)
你可以使用委托,这可以做你想要的:
编辑:简化了一下
static void Main(string[] args)
{
TryCatch(() => { throw new NullReferenceException(); },
new [] { typeof(AbandonedMutexException), typeof(ArgumentException), typeof(NullReferenceException) },
ex => Console.WriteLine(ex.Message));
}
public static void TryCatch(Action action, Type[] exceptions, Action<Exception> catchBlock)
{
try
{
action();
}
catch (Exception ex)
{
if(exceptions.Any(p => ex.GetType() == p))
{
catchBlock(ex);
}
else
{
throw;
}
}
}
您的特定尝试/捕获将是:
bool ret;
TryCatch(
() =>
{
Directory.CreateDirectory(directory);
ret = true;
},
new[]
{
typeof (IOException), typeof (UnauthorizedAccessException), typeof (PathTooLongException),
typeof (DirectoryNotFoundException), typeof (NotSupportedException)
},
ex => lblBpsError.Text = ex.Message
);
return ret;
答案 9 :(得分:0)
我理解其中一些例外可能是不可预见的,但在可能的情况下尝试实施您自己的“先发制人”逻辑。例外是昂贵的,但在这种情况下可能不是一个交易破坏者。
例如,使用Directory.GetAccessControl(...)而不是依赖于抛出UnauthorizedAccessException。
答案 10 :(得分:0)
从The Exception Handling Application Block查看EntLib。他们阐述了一种非常好的基于策略和配置的异常处理方法,避免了大的条件逻辑块。