C#如何处理多个相同的异常?
在我的代码中,我有一个包含多个catch语句的方法,这些语句执行所有相同的语句。我不确定这是正确的方法来实现这一点。你会怎么做C#如何处理多个相同的异常?,c#,asp.net,.net,exception,C#,Asp.net,.net,Exception,在我的代码中,我有一个包含多个catch语句的方法,这些语句执行所有相同的语句。我不确定这是正确的方法来实现这一点。你会怎么做 public void LoadControl(ControlDestination controlDestination, string filename, object parameter) { try { // Get filename with extension string file = GetControlF
public void LoadControl(ControlDestination controlDestination, string filename, object parameter)
{
try
{
// Get filename with extension
string file = GetControlFileName(filename);
// Check file exists
if (!File.Exists(file))
throw new FileNotFoundException();
// Load control from file
Control control = LoadControl(filename);
// Check control extends BaseForm
if (control is BaseForm)
{
// Set current application on user control
((BaseForm)control).CurrentApplication = this;
((BaseForm)control).Parameter = parameter;
// Set web user control id
control.ID = filename;
Panel currentPanel = null;
switch (controlDestination)
{
case ControlDestination.Base:
// Set current panel to Base Content
currentPanel = pnlBaseContent;
// Set control in viewstate
this.BaseControl = filename;
break;
case ControlDestination.Menu:
// Set current panel to Menu Content
currentPanel = pnlMenuContent;
// Set control in ViewState
this.MenuBaseControl = filename;
break;
}
currentPanel.Controls.Clear();
currentPanel.Controls.Add(control);
UpdateMenuBasePanel();
UpdateBasePanel();
}
else
{
throw new IncorrectInheritanceException();
}
}
catch (FileNotFoundException e)
{
HandleException(e);
}
catch (ArgumentNullException e)
{
HandleException(e);
}
catch (HttpException e)
{
HandleException(e);
}
catch (IncorrectInheritanceException e)
{
HandleException(e);
}
}
HandleException就是这样的:
private void HandleException(Exception exception)
{
// Load error control which shows big red cross
LoadControl(ControlDestination.Menu, "~/Controls/Error.ascx", null);
// Store error in database
DHS.Core.DhsLogDatabase.WriteError(exception.ToString());
// Show error in errorbox on master
Master.ShowAjaxError(this, new CommandEventArgs("ajaxError", exception.ToString()));
}
您的做法是正确的(您应该只捕获要处理的异常,并且无法在一个catch
块中捕获多个异常类型),但是作为替代方法,您可以只catch(exception ex)
,检查异常类型,如果它不是您期望的,请再次抛出它,如下所示:
var exceptionTypes=new Type[] {
typeof(FileNotFoundException),
typeof(ArgumentNullException),
//...add other types here
};
catch(Exception ex) {
if(exceptionTypes.Contains(ex.GetType()) {
HandleException(ex);
} else {
throw;
}
}
try
{
// code that throws all sorts of exceptions
}
catch(Exception e)
{
HandleException(e);
}
更新:使用C#6(与Visual Studio 2015一起推出),您可以执行以下操作:
catch(Exception ex) when (exceptionTypes.Contains(ex.GetType()) {
HandleException(ex);
}
这样写:
var exceptionTypes=new Type[] {
typeof(FileNotFoundException),
typeof(ArgumentNullException),
//...add other types here
};
catch(Exception ex) {
if(exceptionTypes.Contains(ex.GetType()) {
HandleException(ex);
} else {
throw;
}
}
try
{
// code that throws all sorts of exceptions
}
catch(Exception e)
{
HandleException(e);
}
编辑:请注意,这是对您的问题的直接回答,而不是对这是否是推荐做法的评论
edit2:但是,如果
e
的类型是异常的特定列表,则可以在函数中进行测试,如果不是,则可以重新显示它。异常处理性能不是问题,因为它意味着。。。首先是例外。我将重构如下:-
public class Sample
{
public void LoadControl( ControlDestination controlDestination, string filename, object parameter )
{
HandleExceptions( HandleException, () =>
{
//.... your code
} );
}
private void HandleExceptions( Action<Exception> handler, Action code )
{
try
{
code();
}
catch ( FileNotFoundException e )
{
handler( e );
}
catch ( ArgumentNullException e )
{
handler( e );
}
catch ( HttpException e )
{
handler( e );
}
catch ( IncorrectInheritanceException e )
{
handler( e );
}
}
private void HandleException( Exception exception )
{
// ....
}
}
公共类示例
{
public void LoadControl(ControlDestination ControlDestination,字符串文件名,对象参数)
{
HandleException(HandleException,()=>
{
//……你的密码
} );
}
私有void HandleExceptions(操作处理程序、操作代码)
{
尝试
{
代码();
}
catch(filenotfounde异常)
{
处理程序(e);
}
捕获(e)
{
处理程序(e);
}
catch(httpe异常)
{
处理程序(e);
}
捕获(不正确的删除异常e)
{
处理程序(e);
}
}
私有void HandleException(异常)
{
// ....
}
}
如果我使用的是VB.NET,我会使用异常过滤器来执行一系列捕获。但是,当我们使用C#时,您使用的方法是最有效的方法,而不是
private void HandleExceptions( Action<Exception> handler, Action code )
{
try
{
code();
}
catch ( Exception e )
{
if ( e is FileNotFoundException
|| e is ArgumentNullException
|| e is HttpException
|| e is IncorrectInheritanceException )
handler( e );
else
throw;
}
}
private void HandleExceptions(操作处理程序,操作代码)
{
尝试
{
代码();
}
捕获(例外e)
{
如果(e)是FileNotFoundException
||e是一个例外
||e是HttpException
||e是不正确的(例外)
处理程序(e);
其他的
投掷;
}
}
我将以一种语言不可知的方式回答这个问题:
1.
您现在所做的是正确的。它没有什么问题,只是如果你做了很多次,它可能会变得单调乏味
2.
捕获最常见的异常形式。简单地
catch(Exception e)
{
...
}
3.
也许您只想捕获一些异常,而不想捕获所有异常,如果您只是这样做了,您就会这样做
执行#2中的操作,并修改HandleException以仅处理某些类型的异常。这样,您将只需要执行一次tem输出,而且它仍然比上面的更紧凑
private void HandleException(Exception e) throws Excpetion
{
// Reject some types of exceptions
if (!((e is FileNotFoundException) ||
(e is ArgumentNullException) ||
(e is HttpException ) ||
(e is IncorrectInheritanceException )))
{
throw;
}
//Rest of code
...
}
编辑:
我知道科纳米曼有第三种选择。我说去吧。我会这样做
public void LoadControl(ControlDestination controlDestination, string filename, object parameter)
{
try
{
// Get filename with extension
string file = GetControlFileName(filename);
// Check file exists
if (!File.Exists(file))
throw new FileNotFoundException();
// Load control from file
Control control = LoadControl(filename);
// Check control extends BaseForm
if (control is BaseForm)
{
// Set current application on user control
((BaseForm)control).CurrentApplication = this;
((BaseForm)control).Parameter = parameter;
// Set web user control id
control.ID = filename;
Panel currentPanel = null;
switch (controlDestination)
{
case ControlDestination.Base:
// Set current panel to Base Content
currentPanel = pnlBaseContent;
// Set control in viewstate
this.BaseControl = filename;
break;
case ControlDestination.Menu:
// Set current panel to Menu Content
currentPanel = pnlMenuContent;
// Set control in ViewState
this.MenuBaseControl = filename;
break;
}
currentPanel.Controls.Clear();
currentPanel.Controls.Add(control);
UpdateMenuBasePanel();
UpdateBasePanel();
}
else
{
throw new IncorrectInheritanceException();
}
}
catch (Exception e)
{
HandleException(e);
}
}
public void HandleException(Exception e)
{
if (e is FileNotFoundException
|| e is ArgumentNullException
|| e is HttpException
|| e is IncorrectInheritanceException)
{
// Load error control which shows big red cross
LoadControl(ControlDestination.Menu, "~/Controls/Error.ascx", null);
// Store error in database
DHS.Core.DhsLogDatabase.WriteError(exception.ToString());
// Show error in errorbox on master
Master.ShowAjaxError(this, new CommandEventArgs("ajaxError", exception.ToString()));
}
}
您可以使用泛型来获得更好的解决方案,只要您不介意也使用Lambda。我不喜欢开机型。我已经使用过几次这段代码,我发现它对于服务代理特别有用,在服务代理中,您希望以相同的方式处理大量异常。如上所述,在可能的情况下,最好捕获正确类型的异常 代码通过将异常指定为handle函数的泛型类型参数来工作。然后捕获这些特定类型,但将其作为基类传递给泛型处理程序。我没有添加手动箭头,但可以根据需要添加。也可以根据您的喜好更改命名
public static void Handle<T>(Action action, Action<T> handler)
where T : Exception
{
try
{
action();
}
catch (T exception)
{
handler(exception);
}
}
public static void Handle<T1, T2>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
}
public static void Handle<T1, T2, T3>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
where T3 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
catch (T3 exception)
{
handler(exception);
}
}
public static void Handle<T1, T2, T3, T4>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
where T3 : Exception
where T4 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
catch (T3 exception)
{
handler(exception);
}
catch (T4 exception)
{
handler(exception);
}
}
}
public class Example
{
public void LoadControl()
{
Exceptions.Handle<FileNotFoundException, ArgumentNullException, NullReferenceException>(() => LoadControlCore(10), GenericExceptionHandler);
}
private void LoadControlCore(int myArguments)
{
//execute method as normal
}
public void GenericExceptionHandler(Exception e)
{
//do something
Debug.WriteLine(e.Message);
}
}
公共静态无效句柄(操作,操作处理程序)
其中T:异常
{
尝试
{
动作();
}
捕获(T异常)
{
处理程序(例外);
}
}
公共静态无效句柄(操作,操作处理程序)
其中T1:异常
其中T2:例外
{
尝试
{
动作();
}
捕获(T1异常)
{
处理程序(例外);
}
捕获(T2异常)
{
处理程序(例外);
}
}
公共静态无效句柄(操作,操作处理程序)
其中T1:异常
其中T2:例外
其中T3:例外
{
尝试
{
动作();
}
捕获(T1异常)
{
处理程序(例外);
}
捕获(T2异常)
{
处理程序(例外);
}
捕获(T3异常)
{
处理程序(例外);
}
}
公共静态无效句柄(操作,操作处理程序)
其中T1:异常
其中T2:例外
其中T3:例外
其中T4:例外情况
{
尝试
{
动作();
}
捕获(T1异常)
{
处理程序(例外);
}
捕获(T2异常)
{
处理程序(例外);
}
捕获(T3异常)
{
处理程序(例外);
}
捕获(T4例外)
{
处理程序(例外);
}
}
}
公开课范例
{
公共void LoadControl()
{
句柄(()=>LoadControlCore(10),GenericeExceptionHandler);
}
私有void LoadControlCore(int-myArguments)
{
//正常执行方法
}
公共真空发生器