【问题标题】:.Net exception catching in subclasses.Net 子类中的异常捕获
【发布时间】:2012-08-25 18:18:52
【问题描述】:

在 .net 中,我如何让编写子类的人意识到他们需要为基类可能抛出的特定异常类型编写代码?理想情况下,我希望强制开发人员尝试..捕获异常或在异常发生之前执行必要的验证...我是否可以使用属性来强制开发人员为异常编写代码?

例如....

我有一些调用“保存”方法的代码。在对象上调用 save 之前,我有一个提供一些验证的拦截类。如果一个类不是处于有效状态,那么我会抛出一个异常(我正在查看的不是我的代码,所以此时不​​使用异常不是一个可接受的解决方案......),我想知道的是我如何向我的代码的使用者表明他们应该检查潜在的异常并对其进行编码,或者至少执行检查以使异常不会发生......?

简单来说(我的代码使用了很多接口等,所以这只是一个简单的例子......)

class SavableObject {
    public static void Save(){
        // validation
        ValidationClass.BeforeSave();
        // then do the save... 
        DoSave();
    }
    public static void DoSave(){
        // serialize...
    }
}

class ValidationClass {
    public static void BeforeSave(T cls){
        // perform some checks on class T
        // THROW EXCEPTION if checks fail
    }
}

所以在这个例子中,我的代码的消费者将继承自 SavableObject,如下所示,然后可以调用 save... 例如...

class NewSavableThing: SavableObject
{
    public static void Save(){
        base.Save();
        // calls inherited save method which may throw an exception
        // At this point the exception may still occur, and the person writing this 
        // code may not know that the exception will occur, so the question is how do 
        // I make this clear or force the developer of this class to code for 
        // the possibility that the exception may occur?!
    }
}

我想知道是否可以使用一组属性,这样我就可以强制构建子类的人为异常编写代码...例如...

class SavableObject {
    [DeveloperMustCatchException(T)] // specifies that the exception type must be caught
    public static void Save(){ ... }
}


class NewSaveableThing: SavableObject {
    [ExceptionIgnored] / [ExceptionCaught] // specifies that the developer is aware 
    // that the exception needs catching/dealing with, I am assuming that 
    // if this attribute is not provided then the compiler will catch 
    // and prevent a successful compile...
    public static void Save() {
    }
}

任何指针都非常感谢...

编辑:澄清 - 我想强制开发人员承认存在异常,这样开发人员就不能不知道异常。理想情况下,如果缺少 [ExceptionIgnored] 属性或 [ExceptionHandled](或类似)属性,编译器将停止编译......这表明已考虑到异常。我不介意忽略异常,我想做的是确保下一个开发人员知道异常的存在——如果这有意义的话。我知道在 /// 注释中我可以记录异常...

我问是因为我有几个与我们一起工作的学生不知道异常并且没有阅读所有文档,即使异常已经记录在案。我无法检查他们编写的每一行代码,所以我希望强迫他们承认异常并让编译器为我检查是否考虑了异常......只要他们是,他们是否为异常编写代码是他们的选择意识到它的存在...

【问题讨论】:

    标签: .net exception attributes


    【解决方案1】:

    使用 XML 文档(方法头中的 /// cmets),特别是 exception tag:

    标签让你指定可以抛出哪些异常。

    让人们知道可能会发生异常就足够了。他们可以决定抓住它还是让它升级。

    编辑

    事实上,您也可以使用 Java 的 throws 关键字。不幸的是,它在 C# 中是 does not exist

    【讨论】:

    • 同意 /// 将提供注释 - 但我希望编译器进行检查,以便开发人员不能简单地忽略异常......
    • 是的,但他们不应该有义务抓住它。不无知是他们的责任。记录下来就足够了。
    • 现在您在谈论已检查和未检查的异常?这不是我想要的......我希望我可以使用属性来强制程序员考虑(不一定处理)异常的义务......
    • 是的,我明白你的意思,我理解你的动机,我只是不同意:)。让学生编写生产代码总是有风险的。敦促他们编写单元测试!
    【解决方案2】:

    我认为处理这种情况最简洁的方法是使用模板方法进行保存,并要求子类在抛出异常时提供错误处理程序的实现:

    public abstract class SaveableObject
    {
        public void Save()
        {
            try
            {
                ValidationClass.BeforeSave();
                this.SaveCore();
            }
            catch(ExceptionType ex)
            {
                OnSaveException(ex);
            }
        }
    
        protected abstract void OnSaveException(ExceptionType ex);
        protected abstract void SaveCore();
    }
    

    【讨论】:

    • @0909EM - 我不确定你的意思 - 如果子类的作者未能通过覆盖处理程序方法来确认异常,则此代码将无法编译。
    • 对不起!是的,你的正确......它将在编译时检查! (称之为高级时刻?!)我想得越多,我就越喜欢这个解决方案......这比用属性/代码合同等炮制一些东西要容易得多!!!
    • 郑重声明:我同意它在本地级别执行您想要的操作,但不可能在您想要强制异常感知的任何地方应用此模式。很快你就会遇到继承限制(没有多重继承)提到一件事。那么Save() 的消费者呢?如果OnSaveException 没有“吃掉”异常而是重新抛出异常怎么办?
    【解决方案3】:

    不应强迫开发人员在其代码中捕获和处理异常。如果他们的代码不能合理地从异常原因中恢复,那么不应该被捕获,并且异常应该冒泡。

    【讨论】:

    • 好的 - 我可以理解 - 但我希望编译器进行尽可能多的检查,以便开发人员可以选择忽略异常,但不能忽视它的发生。 .
    【解决方案4】:

    没有办法让编译器按照你的要求去做。让编译器检查对象状态正确性的最接近方法是使用代码协定 http://msdn.microsoft.com/en-us/library/dd264808.aspx

    【讨论】:

    • 这可能是我将得到的最接近的答案......理想情况下,我会在编译时执行检查,但我同意这可能是最接近的......
    猜你喜欢
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多