处理不在c#中抛出异常的类

时间:2010-08-04 11:51:47

标签: c# exception exception-handling try-catch

我有一些看起来像这样的UI代码:

try
{
    SomeClass classInstance = new SomeClass(someId);
}
catch (Exception exception)
{
    // Content wasn't created, show a message, stop processing
    return;
}

似乎添加了try catch,因为SomeClass的构造函数会弹出,如果它接收的someId无效,并且在数据库中找不到数据。

最近通过FXCop运行此代码,它警告不要使用常规Exception,但所有SomeClass都会抛出一个新的Exception,并带有一条消息,说它无法初始化。

我想问题是类构造函数应该有它自己的自定义异常,然后我可以在我的UI中处理,但我想知道我还能对上面的代码做什么来处理异常,满足FXCop的要求?

6 个答案:

答案 0 :(得分:4)

FxCop的规则存在是因为上面的catch (Exception)块捕获了所有可能的异常,包括您可能无法以有用的方式捕获的StackOverflowException等低级异常。

正确的方法肯定是抛出一种更具体的类型:您发明的一种类型,或者与您的情况非常匹配的现有.NET框架异常类型。 (如果有疑问,我通常会去InvalidOperationException。)

或者,您可以在捕获时检查确切的异常类型。这不会阻止FxCop警告,但它应该解决潜在的问题:

catch (Exception exception)
{
    if (exception.GetType() == typeof(Exception))
    {
        // Content wasn't created, show a message, stop processing
        return;
    }
    else
    {
        // Some other exception type that wasn't thrown from our code -
        //    delegate to a higher-level exception handler
        throw;
    }
}

答案 1 :(得分:3)

您不需要自定义例外;在给定的情况下,只使用框架中已存在的数十个中的一个。如果someId不好,请抛出ArgumentException - 这就是它的用途。如果某些东西不为null,则会出现NullReferenceException;只是让它被抛出。等等。抛出一个简单的Exception有点像说“出了问题 - 阅读信息以获取详细信息”而不是“这出错”。

FxCop正在抱怨catch (Exception),因为它常常被滥用来吞没所有异常,而不是让它们传播并由知道如何操作的代码处理。你应该能够说出抛出什么类型的异常并捕获它们,同时让那些你不认识的异常进入调用堆栈。

答案 2 :(得分:2)

您应该修复类构造函数。投掷Exception 永远不会一个好主意。

但是,要暂时解决这个问题(因为这是一个可怕的,不可靠的黑客攻击),你可以检查异常的消息,而不是你期望的消息:

catch (Exception exception)
{
    if (exception.Message == "whatever your class sets the message to")
        // Content wasn't created, show a message, stop processing
        return;
    else
        // Any other exception should bubble
        throw;
}

答案 3 :(得分:0)

使用InvalidOperationException代替投掷Exception听起来似乎是明智的。

答案 4 :(得分:0)

如果FXCop不喜欢处理一般的Exception(我倾向于同意),那么也许你可以访问SomeClass的源代码。修改构造函数以抛出更具体的异常,例如ArgumentOutOfRangeException或一些自定义异常。

在这种情况下,您的代码将如下所示:

try
{
   SomeClass classInstance = new SomeClass(someId);
}
catch(ArgumentOutOfRangeException exception)
{
   // Content wasn't created, show a message, stop processing
   return;
}

答案 5 :(得分:0)

正如许多其他人所说,构造函数不应该抛出一个裸Exception。看到构造函数从DB检索数据并根据结果抛出,最好的解决方案是创建自己的异常类。

在Visual Studio中创建异常非常容易。只需输入Exception并按 TAB 即可。然后,它将使用所需的构造函数(所有四个)创建异常类。不要害怕创建不那么做的课程,这就是他们的目的。

这就是我写这个课的方式:

public class SomeClass {
    public SomeClass(int someId) {
        if (someId < 0) //validation on the ID, can it be negative?
            throw new ArgumentException("someId", "ID cannot be negative");

        //Perform DB operation
        if (/*DB error - not found*/)
            throw new DataNotFoundException("Cannot find record with ID " + someId);
    }
}

[Serializable]
public class DataNotFoundException : Exception {
    public DataNotFoundException() { }
    public DataNotFoundException(string message) : base(message) { }
    public DataNotFoundException(string message, Exception inner) : base(message, inner) { }
    protected DataNotFoundException(
      System.Runtime.Serialization.SerializationInfo info,
      System.Runtime.Serialization.StreamingContext context)
        : base(info, context) { }
}