在C#中使用自定义异常时遇到问题

时间:2012-03-10 22:24:50

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

我有一个我在Visual Studio 2010中编写的表单程序。在程序中我写了一个名为 LibraryGeneralExceptions.cs

的新异常文件
namespace Database
{
    public class LibraryGeneralExceptions : Exception
    {
        public LibraryGeneralExceptions()
        {
        }

        public void ItemInsertError()
        {
            MessageBox.Show("Item Insert Error", "Error");
        }

        ...
    }
}

在我所拥有的相同名称空间下

public void ItemInsert(string name,string creator,string publishing,string itemType,string genere, string year)
{
    ...
    if (errorMsg.Length != 0)
    {
       throw new ItemInsertError();
        MessageBox.Show(errorMsg, "error");
    }

在另一个使用数据库并从数据库调用函数的命名空间下我试图设置一个try-catch来捕获数据库将使用LibraryGeneralExceptions进行的异常,但我似乎无法让它因某些原因而起作用。

5 个答案:

答案 0 :(得分:2)

如果您想抛出ItemInsertError,则需要ItemInsertError来自System.Exception的课程:

public class ItemInsertError : Exception
{
}

答案 1 :(得分:2)

这在很多层面都是错的,我不知道从哪里开始。我建议阅读有关异常处理和自定义异常的MSDN文档。

http://msdn.microsoft.com/en-us/library/5b2yeyab.aspx

Visual Studio还提供了一个片段,用于按照最佳实践格式模板自定义异常。

有关详细信息,请参阅http://www.blackwasp.co.uk/VSExceptionSnippet.aspx

答案 2 :(得分:2)

lakovl似乎你可能误解了C#中的异常是如何工作的。您可能希望开始阅读的一个参考点是MSDN article on exceptions and exception handling,请查看子部分。

当抛出异常时,它是故障发生的地方,当被捕获时被处理,并且当通过包装异常重新抛出时,它是您尝试解决故障但不能或只是抓住记录。

相似地想象你有一连串的人,一辆冰淇淋卡车到了,一个人要求别人去给他们买冰淇淋,他们跑到卡车上才发现原来的人没有不给他们足够的钱。冰淇淋供应商抛出异常InsufficientFundsException,由同事抓住并重新抛出。现在,如果同事足够慷慨,他们可能希望为他们添加发现,但如果他们也没有资金,他们将通过包装来重新抛出异常。最后,他们回到原始人(这称为冒泡),然后他们可以解决或放弃。

现在让我们来看看你对异常做了什么。您尝试做的是创建一个异常类型LibraryGeneralExceptions这很好(除了复数形式,删除s)虽然您已经在代码中创建了一个方法ItemInsertError正在将它视为自己的例外。所以让我们试着解决你的问题。

首先看起来好像你打算使用LibraryGeneralExceptions作为子命名空间而ItemInsertError是一个例外,所以这是一个正确的实现:

namespace Database {
    public class ItemInsertError : Exception {
        public ItemInsertError() : base() {}
        public void ItemInsertError(string message) : base(message) {}
    }
}

现在让我们检查一下你的insert方法,首先错误的是你正在处理异常并同时警告用户,而是让我们只处理异常。

public void ItemInsert(string name,
                       string creator,
                       string publishing,
                       string itemType,
                       string genre,
                       string year) {
    // ...
    if (errorMsg.Length != 0) {
       throw new ItemInsertError(errorMsg);
    }
}

所以现在当我们调用ItemInsert方法时,我们将处理该段代码中的异常。

try {
    ItemInsert("name", "creator", "publishing", "itemType", "genre", 2012);
} catch (ItemInsertError ex) {
    MessageBox.Show(
        ex.Message, "Error during insert",
        MessageBoxButtons.OK, MessageBoxIcon.Error);
}

从此您的用户现在可以获得有关错误的反馈,您的客户端代码现在可以尝试恢复,就像我之前的示例决定我们是否可以找到更多资金一样。

答案 3 :(得分:1)

您想要在异常中抛出新的LibraryGeneralExceptions,而不是方法。您不会在异常类中抛出方法 - 您实际上是在抛出异常类本身的实例。这允许您为调用者封装一些可能有用的其他信息(例如抛出时系统的状态,导致异常的数据传递等)。

要立即修复,您应该从LibraryGeneralExceptions的构造函数中调用逻辑。

namespace Database
{
    public class LibraryGeneralExceptions : Exception
    {
        public LibraryGeneralExceptions()
        {
          ItemInsertError();
        }
    }
}

但是,如果你真的想要不同的行为(一个用于ItemInsertError而另一个用于NetworkTimeoutError),你可能想为这些行为创建不同的Exception类。 / p>

答案 4 :(得分:0)

异常是System.Exception类或派生类的实例。您需要从System.Exception派生自定义异常类:

namespace LibraryExceptions {
    public class InsertError : Exception  {

    }
}

throw新的实例。

throw new LibraryExceptions.InsertError()