如何处理调用方法中的错误

时间:2013-02-27 12:53:34

标签: c# oop error-handling

我没有太多以良好OO方式编程的经验,但我想学习,今天发生的情况是,如果我的观察结果正确,我认为我可以提高我的错误处理技能

我有一个事件,代码在逻辑上分为两部分:

private void btnSave_Click(object sender, EventArgs e)
{
    IList<AppConfig> AppConfigs = AppConfigService.All().Where(a => (a.IsActive == true) && (a.ConfigProperty == "MaterialImages")).ToList();
    string ImageNameFilter = txtCode.Text;

    if (!ucFileExplorer.IsSavedImage(AppConfigs, ImageNameFilter))
    {
        MessageBox.Show("Error");
        return;
    }

    if (Save())
    {
        LoadForm<Materials>();
    }
}

第二部分只是调用Save()方法,但我的问题是关于第一部分。在那里,我调用一个方法,该方法应该复制用OpenFileDialog选择的图像,并且整个逻辑在我用于文件浏览的用户控件中,因为我以多种形式使用它。实际执行应对的方法是:

public bool IsSavedImage(IList<AppConfig> AppConfigs, string ImageNameFilter)
{
    bool IsCopied = false;
    try
    {
        string imgPath = AppConfigs[0].ConfigValue.ToString();
        File.Copy(selectedFile, imgPath + "\\" + ImageNameFilter + slectedFileName + ".jpeg");
        IsCopied = true;
    }
    catch (IOException copyError)
    {
        MessageBox.Show("Error saving image!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
    }
    return IsCopied;
}

在这里开始我的问题。我想我在这里需要try-catch子句,因为这是实际执行的地方,并且更容易返回正确的状态(true或false)。但我认为实际的copyError应该在调用方法中处理(在这种情况下我的btn Click事件)。所以我有两个问题,处理这个异常的正确方法是什么,如果我想将它传递给调用该方法的地方,我该怎么办呢?

5 个答案:

答案 0 :(得分:4)

不要在保存功能中显示错误消息对话框。将其重命名为&#34; SaveImage&#34;使用void返回类型并让异常引发。不,如果&#34;在调用者中,但是一个try-catch块,在发生异常时显示错误消息对话框。

答案 1 :(得分:2)

您可以在用户控件中定义事件,并在收到异常时触发它
然后从主父订阅此异常事件并相应地处理它。

像这样。

public Action<Exception> OnExceptionInUserControl;
public bool IsSavedImage(IList<AppConfig> AppConfigs, string ImageNameFilter)
{
    bool IsCopied = false;
    try
    {
        string imgPath = AppConfigs[0].ConfigValue.ToString();
        File.Copy(selectedFile, imgPath + "\\" + ImageNameFilter + slectedFileName + ".jpeg");
        IsCopied = true;
    }
    catch (IOException copyError)
    {
        OnExceptionInUserControl(copyError);
        return false;
    }
    return IsCopied;
}
主窗口中的

userControl.OnExceptionInUserControl += new Action<Exception>(ExceptionEventHandler);

答案 2 :(得分:2)

  

处理此异常的正确方法是什么

这取决于你的申请;通常,您处理需要(或可以!)处理它的异常。例如,在您可以收集更多信息和/或对错误做出反应的地方(显示错误消息,记录,重试......)

  

如果我想将它传递给调用方法的地方,我该怎么办?

您只需处理更高级别的异常:异常非常方便,因为它们会传播给调用方,直到有人捕获它们为止。只需在调用函数中插入try... catch块(注意考虑所有执行路径,或者找不到任何处理它们的函数的异常将被删除,终止程序)。

一般来说,我记得在应用程序中处理错误的四种主要方式:返回值(错误代码或布尔值),异常,GetLastError - 样式(在某处存储错误代码,让程序员调用函数检索它),回调(提供一个在发生错误时调用的函数)。

有一段时间,例外处理是处理错误的OO方式。但是你现在在精心设计的框架中也有事件处理程序(毕竟是回调的特例)。

一般来说,一个好的设计应该选择一个并坚持下去,最终将一种错误类型“转换”为另一种错误类型(例如,从第三方代码中捕获异常并使它们成为回调,如在Umar Farooq Khawaja中回答)

答案 3 :(得分:2)

我同意dutzu,实际的错误检查应该在业务层完成。除此之外,我建议你的UI组件或表单应该公开一个ErrorHandler事件,你应该在出现错误时提出这个事件。

这样,如果有一个错误处理程序附加到错误事件处理程序,那么将调用它,并且如果需要,错误处理程序可以采取适当的操作。

您可以定义ErrorEventHandler委托,例如:

public void ErrorEventHandler(object sender, ErrorEventArgs e);

ErrorEventArgs类如:

public class ErrorEventArgs : EventArgs
{
    // error info exposed via readonly properties
}

您可以在UI组件/表单中创建错误事件,如下所示:

public class UIForm
{
    public event ErrorEventHandler ErrorOccurred;

    protected void RaiseErrorEvent(ErrorEventArgs e)
    {
        ErrorEventHandler eh = ErrorOccurred;

        if (eh != null)
        {
            eh.Invoke(this, e);
        }
    }

    private void btnSave_Click(object sender, EventArgs e)
    {
        IList<AppConfig> AppConfigs = AppConfigService.All().Where(a => (a.IsActive == true) && (a.ConfigProperty == "MaterialImages")).ToList();
        string ImageNameFilter = txtCode.Text;

        try
        {
            if (!ucFileExplorer.IsSavedImage(AppConfigs, ImageNameFilter))
            {
                RaiseErrorEvent(new ErrorEventArgs());
                return;
            }

            if (Save())
            {
                LoadForm<Materials>();
            }
        }
        catch (Exception exception)
        {
            // convert exception to an ErrorEventArgs e here
            RaiseErrorEvent(e);
        }
    }
}

答案 4 :(得分:1)

我不会以这种方式捕获异常,因为这当前不一致:您的方法仅捕获IOException个异常,因此它可能抛出其他不会被捕获的异常(未在{{ 1}}或调用方法),例如IsSavedImage

我看到的另一个问题是,如果UnauthorizedAccessException异常,您始终会显示一个消息框。我会删除此部分,因为有一天您可能希望以不同方式处理异常,并且您不希望更改核心/业务功能中当前处理的方式。

例如:

IOException
相关问题