首页 > 解决方案 > 销毁类时如何正确抛出异常?

问题描述

我想在我的 C# 类中使用 IDisposable 模式,以便稍后将其包装在“使用块”中。我的问题是,当班级被处置时,如果不满足特定条件,我希望有时能够抛出异常。

我知道从技术上讲,我可以在 Dispose 方法或类的破坏中抛出异常,但似乎不鼓励这样做,根据微软的这篇文章


class PersonListBuilder : IDisposable
{
    private readonly List<Person> _persons = new List<Person>();

    public PersonListBuilder SetName(string name)
    {
        _name = name;
        return this;
    }

    public PersonListBuilder SetAge(int age)
    {
        _age = age;
        return this;
    }

    public PersonListBuilder Push()
    {
        _persons.Add(new Person
        {
            Name = _name,
            Age = _age,
        }
        PrepareForNewPerson();
    }

    public List<Person> Build()
    {
        //Because of other implementation details, I cannot call method 'ThrowExceptionIfUnPushedPersonExists' here
        return _persons;
    }

    private void PrepareForNewPerson()
    {
        _name = string.Empty;
        _age = default;
    }

    private void ThrowExceptionIfUnPushedPersonExists()
    {
        if(!string.IsNullOrEmpty(_name) || age != 0)
        {
            throw new Exception("Seems there is an unpushed person");
        }
    }

    public void Dispose()
    {
        //Call below method here is discouraged :(
        ThrowExceptionIfUnPushedPersonExists()
    }
}

class PersonBuilderConsumer
{

    public void MakePersons()
    {
        //What I'd like to do
        try
        {
            using(var personListBuilder = new PersonListBuilder())
            {
                //We won't call the 'Push' method below, so an exception will be throw
                var persons = personListBuilder.SetName("Jane")
                    .SetAge(36)
                    .Build();
            }
        }
        catch(Exception e)
        {
            // unpushed person exception should get thrown then handled here
        }
    } 
}

理想情况下,我想使用示例中显示的代码,但同样,根据此 Microsoft 帖子,“Dispose”方法位于不鼓励抛出异常的位置列表中。有没有更好的方法让我的构建器在输入有效时返回预期结果但如果输入错误则失败?

我当然可以调用公开方法“ThrowExceptionIfUnPushedPersonExists”,并在“使用块”结束之前自己调用它,但我担心我可能会忘记这样做,这会使生成器“不可信”。

标签: c#exceptiondestructoridisposable

解决方案


推荐阅读