投掷后程序崩溃的原因是什么?

时间:2015-09-12 16:18:04

标签: c# exception

我试图用你自己的例外来理解try / catch / throw ..

这是我的自定义异常类:

[Serializable]
class CustomException : FormatException
{
    /// <summary>
    /// Just create the exception
    /// </summary>
    public CustomException()
       : base()
    { }

    /// <summary>
    /// Create the exception with description
    /// </summary>
    /// <param name="message">Exception description</param>
    public CustomException(String message)
        : base(message)
    { }

    /// <summary>
    /// Create the exception with description and inner cause
    /// </summary>
    /// <param name="message">Exception description</param>
    /// <param name="innerException">Exception inner cause</param>
    public CustomException(String message, Exception ex)
        : base(message, ex)
    {
        MessageBox.Show(message + ex.Message);
    }
}

这是我使用它的地方:

public static int ParseInput(string inInt)
{
    try
    {
        int input = int.Parse(inInt);
        return input;
    }
    catch (FormatException e)
    {
        throw new CustomException("Only use numbers! ", e);
    }
}

现在当我运行程序但是在一个char程序崩溃时它显示MessageBox然后程序停止..并显示带有此信息的经典错误窗口:类型未处理的异常&#39; Spelregistrering.CustomException&# 39;发生在Spelregistrering.exe

我希望程序在异常之后运行,就像它始终使用原始的try / catch一样...我还没有理解或错过什么?

编辑: 我知道TryParse,这段代码我只是为了更好地理解自定义异常!而你的回答表明我显然还没有理解他们......

4 个答案:

答案 0 :(得分:1)

例外情况是不显示MessageBox,而是告诉您可以处理的事情是严重错误的。抛出一个新的Exception是没有意义的,声明一个自定义的也没有意义。

在你的情况下,你应该做这样的事情:

try
{
    int input = int.Parse(inInt);
    return input;
}
catch (FormatException e)
{
     MessageBox.Show("Only use numbers! " + e.Message);
     //you may return something here to make your ParseInput compilable.
}

您的代码中发生的事情是,引发了一个异常,您抓住了然后立即抛出了一个新的异常,这个异常并未在任何地方被捕获并导致崩溃。

当您存在某些特定的关键状态时,您应该声明自己的例外情况,以便让代码用户知道发生的事情 - 基本上不是抛出Exception的实例,这太笼统了,你可以创建自己的例外,这将更具体。

由于堆栈注册,抛出异常是相当昂贵的操作。在您的情况下,您可以使用int.TryParse来避免例外。

int input;    
if (int.TryParse(inInt, out input))
{
    //do something with the input.
}
else
{
    MessageBox.Show("Only use numbers!");
}

修改

正如Arthur所建议的那样,本文中建议的try-catch不能在ParseInput中使用,因为catch中的程序步骤将不会从该方法返回任何内容。要解决此问题,我建议您不要实施并调用ParseInput方法,并使用此回复中发布的int.TryParse代码段。

答案 1 :(得分:0)

为了得到我的两个便士,你可以这样做

public static int ParseInput(string inInt)
{
    int input;
    if (!int.TryParse(inInt, out input)) MessageBox.Show("Only use numbers!");

    return input;
}

如果成功解析,这将返回解析的值,否则它将告诉用户并返回0。

答案 2 :(得分:0)

我现在已将代码更改为:

public static int ParseInmatning(string inInt)
{
    try
    {
        int input = int.Parse(inInt);
        return input;
        throw new CustomException("Wrong format");
    }
    catch (FormatException e)
    {
        MessageBox.Show("Only use numbers! " + e.Message, "ERROR!");
        return -1;
    }
}

和测试异常类:

[Serializable]
class CustomException : FormatException
{
    /// <summary>
    /// Just create the exception
    /// </summary>
    public CustomException()
    : base() {
    }

    /// <summary>
    /// Create the exception with description
    /// </summary>
    /// <param name="message">Exception description</param>
    public CustomException(String message)
    : base(message) {
    }

    /// <summary>
    /// Create the exception with description and inner cause
    /// </summary>
    /// <param name="message">Exception description</param>
    /// <param name="innerException">Exception inner cause</param>
    public CustomException(String message, Exception ex)
    : base(message, ex) {
    }
}

现在这是正确的吗? gha我不明白这个...... :(并且nooo指南在一个很好的水平解释这个!

答案 3 :(得分:0)

Newbie1337's answer他/她自己的问题是为此提供一个新信息,所以我会尽力根据新信息回答它。

我建议阅读此article,基本上说,只有在有充分理由的情况下才应使用自定义异常。此处SO上还有this post关于使用自定义例外的原因。

首先,我们应该找到自定义异常的原因。

想象一下,我们正在创建一些框架,我们希望用户能够捕获可能从中抛出的所有异常 - 因此异常与框架的功能有关。

为此,我们需要创建一个源自OurFrameworkException的自定义异常Exception。 (这个例外应该是abstract)。

不要无聊,我们可以在其中添加错误代码:

[Serializable]
public abstract OurFrameworkException : Exception
{
    public int ErrorCode { get; private set; }

    public OurFrameworkException(int errorCode)
    {
        ErrorCode = errorCode;
    }
}

然后,当我们实现我们的框架时,我们将遇到需要自定义异常的情况。

将框架视为代码验证的工具(如果可能的话,可能设计不当)。为了使它工作,我们将假设为了讨论,我们必须首先向框架提供一些规则,然后自己运行验证,由于某种原因我们不能在构造函数中执行此操作。例如,可以动态地改变规则。如果没有规则并且运行验证,我们应该抛出InvalidOperationException说我们必须先输入规则。但上面提到的原始请求是,与框架相关的所有异常应该有一个共同的基类来区分它们与它相关。因此,我们需要实施OurFrameworkInvalidOperationException派生的OurFrameworkException

[Serializable]
public OurFrameworkInvalidOperationException : OurFrameworkException
{
    public OurFrameworkInvalidOperationException(string description)
        : base(1) //for example
    {
        // store the description
    }
}

现在为了讨论,让我们对#34;框架#34进行相当愚蠢的实现。

public class OurFramework
{
    string rules;        

    public void SetRules(string rules)
    {
        this.rules = rules;
    }

    public bool IsValid(string input)
    {
        if (!string.IsNullOrEmpty(rules)
        {
            return input == rules; //valid state is when the input is the same as the rules
        }
        else
        {
            throw new OurFrameworkInvalidOperationException("specify rules first");
        }
    }
}

这就是有人会如何使用我们非常聪明的&#34;框架:

OurFramework framework = new OutFramework();
//some inicialization
//the user should call here: framework.SetRules("rule");
bool isValid = false;
try
{
    isValid = framework.Validate(input);
}
catch(OurFrameworkInvalidOperationException)
{
    //tell the user that the rules are not filled in in the GUI somewhere.
}
catch(OurFrameworkOtherException)
{
    //give the user a similar warning as previously about something else.
}
catch(OurFrameworkException)
{
    //a general unspecified framework error occurred in the framework.
}
catch(Exception) //everything else
{
    //something unrelated to the framework or unhandled in the framework occurred.
}

if (isValid)
{
    //do stuff.
}

最后,这是关于如何实现自定义异常的许多articles之一。