c#专业错误处理

时间:2015-08-17 13:12:36

标签: c# error-handling

我正在尝试学习专业错误处理技术,但我无法理解它们的概念,尽管我已经阅读了MSDN和CodePlex上的一些文章。

我将尝试证明我对简化示例的关注。我唯一的错误处理请求是我不希望我的程序退出,只是因为发生了错误。我希望能够看到错误是什么,但是如果文件中有更多错误,我希望在进程完成后看到所有错误的列表(目前我将所有错误消息存储在变量中,我然后刷新到StreamWriter到文件)。

我已经读过您可以使用自定义 ApplicationException 类来处理自定义错误,如下所示:

public class CustomException : ApplicationException
{
    public CustomException() : base() { }
    public CustomException(string sMessage) : base(sMessage) { }
}

以下是代码示例: 我们正在使用的头等舱

public class Person
{
    public Person(string _Name, int _Age)
    {
        this.Name = _Name;
        this.Age = _Age;
    }

    public string Name { get; set; }
    public int Age { get; set; }
}

现在是一个用于某些工作的类:

public class MyWorker
{
    //here we store errors
    public string sErrorMessage { get; set; }

    public void DoStuff()
    {
        //reset variables
        sErrorMessage = string.Empty;

        try
        {
            //create new array of employees
            List<Person> Employees = new List<Person>()
        {
            new Person("Steven",30),
            new Person("John",26),
            new Person("Anna",18)
        };

            //first check if value is not null
            if (Employees == null || Employees.Count == 0)
            {
                throw new CustomException("Employee array is empty. Nothing to validate!");
            }

            //Data validation
            foreach (var item in Employees)
            {
                if (item.Name == "John")
                    throw new CustomException("John is not allowed!");

                if (item.Age < 21)
                    throw new CustomException("Person has to be older than 21!");
            }
        }
        catch (CustomException ex)
        {
            InsertErrorMessage(ex.Message);
        }
    }
    public void InsertErrorMessage(string sMessage)
    {
        sErrorMessage += Environment.NewLine + sMessage;
    }
}

现在我正在进行验证:

    public void DoStuff()
    {
        //reset variables
        sErrorMessage = string.Empty;

        //create new array of employees
        List<Person> Employees = new List<Person>()
        {
            new Person("Steven",30),
            new Person("John",26),
            new Person("Anna",18)
        };

        //first check if value is not null
        if (Employees == null || Employees.Count == 0)
        {
            InsertErrorMessage("Employee array is empty. Nothing to validate!");
        }

        //Data validation
        foreach (var item in Employees)
        {
            if (item.Name == "John")
                InsertErrorMessage("John is not allowed!");

            if (item.Age < 21)
                InsertErrorMessage("Person has to be older than 21!");
        }
    }

对我来说,在try-catch块中捕获异常的唯一好处是,它为您提供了额外的信息,例如检测到错误的行,什么模块给出了错误,......

尽管如此,我认为我不理解这个概念,我的代码使用“正确的”错误处理(或者至少看起来应该是正确的错误处理)是不正确的,必须以不同的方式编写。

有人可以帮助我了解这个真正的附加好处是什么?或者也许分享一些可以解释这个问题的文章/视频?

编辑: 只是一个快速思考 - 也许不会在验证中使用异常,但在诸如“StreamReader试图访问锁定文件”等过程中......?

2 个答案:

答案 0 :(得分:1)

我实际上认为你当前的实现很好。如果你想在没有轰炸的情况下继续执行该程序,那么将所有消息记录到缓冲区并在最后进行刷新的方法都可以。

如果要停止处理,则抛出异常可能是首选方法。如果您想在错误消息中添加一些更详细的内容,可以创建一个文件错误对象,您可以在其中存储可能需要的所有信息,并在写出文件时格式化ToString中的输出。

答案 1 :(得分:1)

我建议像你一样保持验证方法。仅使用异常进行错误处理。如果只查看名称,则验证包含规则而非例外。如果出现意外情况,则会触发异常。

经验法则是不使用异常来构建程序逻辑。

快速谷歌还给了我this code review post,其中还简要讨论了错误处理与验证。

编辑:有人可能会争辩将DoStuff()方法的代码包装在try / catch块中,然后存储一般错误。这样,如果出现意外情况,您的程序将不会崩溃。在这种情况下,我实际上会使用catch(Exception ex)但请确保记录异常以使您的(调试)生活更轻松。