Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#如何处理多个相同的异常?_C#_Asp.net_.net_Exception - Fatal编程技术网

C#如何处理多个相同的异常?

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

在我的代码中,我有一个包含多个catch语句的方法,这些语句执行所有相同的语句。我不确定这是正确的方法来实现这一点。你会怎么做

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)
{
//正常执行方法
}
公共真空发生器