我正在学习异常处理,尤其是对C#的异常处理(我知道,不是最好的主意)。我发现base()方法(?)用于创建自定义异常。虽然我设法创建了一个自定义异常,但我不确定它为什么会起作用。
class Calculator
{
public int power(int n, int p)
{
if(n < 0 || p < 0)
{
throw (new Exp("n and p should be non-negative"));
}
return (int)Math.Pow(n, p);
}
}
public class Exp : System.Exception
{
public Exp(string message) : base(message)
{
//Nothing here
}
}
Calculator.power(n,p)的任务是将n提升到p幂。如果n或p为负数,则抛出异常。
我没有得到的是为什么Exp(&#34; n和p应该是非负的&#34;)打印消息。异常类中没有返回字符串的基础构造函数。
Exp类中唯一存在的构造函数没有任何内容。然而,如果我将一个字符串传递给该构造函数方法,它就会打印出来。
发生了什么事?
答案 0 :(得分:2)
base()
不仅用于创建自定义异常,还用于任何继承情况。您的自定义异常继承自System.Exception
并通过message
调用将其构造函数参数base
传递给基类的构造函数 - 有关详细信息,请参阅base reference。
您在打印输出时看到的行为是因为您的自定义异常继承了System.Exception
.ToString()
的实施。有关该类行为的进一步说明,请参阅System.Exception和Exception(message) constructor。
但重要的是要理解base
对{1}}的使用并不特殊 - 对于任何类继承都是如此 - 但并非所有基类都会提供{{{}的有用实现。 1}}!
答案 1 :(得分:1)
当.NET进程因未处理的异常而退出时,异常会自动打印到控制台。如果您发现异常,则不会打印出任何内容。
答案 2 :(得分:1)
Exception(string)
构造函数重载只是将传递的参数存储到Exception.Message
属性公开的字段中。你可以通过查看reference source for Exception来看清楚这一点。
Message
方法(此处为source for that)中使用 Exception.ToString()
属性。
但是,此消息不会自动&#34;打印&#34;任何地方。这是由CLR在检测到未处理的异常时完成的;它捕获异常,调用.ToString()
,将字符串打印到控制台,然后结束应用程序。
您可以通过自己捕获异常来构建Exception
,轻松看到没有打印:
try
{
var x = new Calculator().power(-1, -2);
}
catch (Exp e)
{
// do nothing
}
除此之外:
尝试遵循C#命名约定。方法是用C#进行的。
自定义异常通常具有Exception
后缀。在您的情况下,您甚至不需要自定义例外,您应该抛出ArgumentException
或ArgumentOutOfRangeException
:
class Calculator
{
public int Power(int n, int p)
{
if (n < 0)
throw new ArgumentOutOfRangeException(nameof(n), "n must be positive");
if (p < 0)
throw new ArgumentOutOfRangeException(nameof(p), "p must be positive");
return (int)Math.Pow(n, p);
}
}