在C#中如何定义自己的例外?
答案 0 :(得分:66)
创建自己的异常的指南(在您的类应该从异常继承的事实旁边)
[Serializable]
属性提供异常使用的公共构造函数:
MyException ();
MyException (string message);
MyException (string message, Exception innerException);
因此,理想情况下,您的自定义Exception
应至少看起来像这样:
[Serializable]
public class MyException : Exception
{
public MyException ()
{}
public MyException (string message)
: base(message)
{}
public MyException (string message, Exception innerException)
: base (message, innerException)
{}
}
关于您是应该继承Exception
还是ApplicationException
这一事实:
FxCop有一条规则,规定你应该避免继承ApplicationException
:
CA1058:Microsoft.Design:
更改 'MyException'的基本类型 它不再延伸 'ApplicationException的'。这个基地 异常类型不提供任何 框架的附加价值 类。扩展'System.Exception'或 现有的未密封异常类型 代替。不要创建新的例外 基本类型,除非有特定的 启用创建的价值 捕获整个类的处理程序 异常。
有关此规则,请参阅the page on MSDN。
答案 1 :(得分:38)
似乎我已经开始了一场Exception sublcassing battle。根据您遵循的Microsoft Best Practices指南,您可以继承System.Exception或System.ApplicationException。有一篇很好的(但是很旧的)博客文章试图消除混乱。我现在将保留我的Exception示例,但您可以阅读帖子并根据您的需要进行选择:
<击> http://weblogs.asp.net/erobillard/archive/2004/05/10/129134.aspx 击>
不再有战斗了!感谢Frederik指出FxCop规则CA1058,该规则声明您的异常应该继承System.Exception而不是System.ApplicationException:
CA1058: Types should not extend certain base types
定义一个继承自Exception的新类(我已经包含了一些构造函数......但你不必拥有它们):
using System;
using System.Runtime.Serialization;
[Serializable]
public class MyException : Exception
{
// Constructors
public MyException(string message)
: base(message)
{ }
// Ensure Exception is Serializable
protected MyException(SerializationInfo info, StreamingContext ctxt)
: base(info, ctxt)
{ }
}
在您的代码中的其他地方抛出:
throw new MyException("My message here!");
修改强>
更新了更改以确保Serializable Exception。详情请见:
Winterdom Blog Archive - Make Exception Classes Serializable
请密切注意有关向自定义类添加自定义属性时需要采取的步骤的部分。
感谢伊戈尔给我打电话!
答案 2 :(得分:12)
定义:
public class SomeException : Exception
{
// Add your own constructors and properties here.
}
扔掉:
throw new SomeException();
答案 3 :(得分:3)
定义:
public class CustomException : Exception
{
public CustomException(string Message) : base (Message)
{
}
}
投掷:
throw new CustomException("Custom exception message");
答案 4 :(得分:0)
来自微软的.NET Core 3.0 docs:
要定义自己的异常类:
定义一个从Exception继承的类。如有必要,定义类需要的任何唯一成员,以提供有关异常的其他信息。例如,ArgumentException类包括一个ParamName属性,该属性指定其参数导致异常的参数的名称,而RegexMatchTimeoutException属性包括一个指示超时间隔的MatchTimeout属性。
如有必要,请覆盖要更改或修改其功能的所有继承的成员。请注意,大多数现有的Exception派生类都不会覆盖继承成员的行为。
确定您的自定义异常对象是否可序列化。序列化使您可以保存有关异常的信息,并允许异常信息由远程上下文中的服务器和客户端代理共享。要使异常对象可序列化,请使用SerializableAttribute属性对其进行标记。
定义异常类的构造函数。通常,异常类具有以下一个或多个构造函数:
Exception(),它使用默认值初始化新异常对象的属性。
Exception(String),它使用指定的错误消息初始化一个新的异常对象。
Exception(String,Exception),它使用指定的错误消息和内部异常初始化一个新的异常对象。
Exception(SerializationInfo,StreamingContext),这是一个受保护的构造方法,它从序列化数据初始化一个新的异常对象。如果选择使异常对象可序列化,则应实现此构造函数。
示例:
using System;
using System.Runtime.Serialization;
[Serializable()]
public class NotPrimeException : Exception
{
private int _notAPrime;
public int NotAPrime { get { return _notAPrime; } }
protected NotPrimeException() : base()
{ }
public NotPrimeException(int value) : base(String.Format("{0} is not a prime number.", value))
{
_notAPrime = value;
}
public NotPrimeException(int value, string message) : base(message)
{
_notAPrime = value;
}
public NotPrimeException(int value, string message, Exception innerException) : base(message, innerException)
{
_notAPrime = value;
}
protected NotPrimeException(SerializationInfo info, StreamingContext context) : base(info, context)
{ }
}
投掷用法:
throw new NotPrimeException(prime, "This is not a prime number."));
尝试/捕获中的用途:
try
{
...
}
catch (NotPrimeException e)
{
Console.WriteLine( "{0} is not prime", e.NotAPrime );
}
答案 5 :(得分:0)
要创建自己的异常,可以使用以下示例:
[Serializable()]
public class InvalidExampleException : System.Exception
{
public InvalidExampleException() : base() { }
public InvalidExampleException(string message) : base(message) { }
public InvalidExampleException(string message, System.Exception inner) : base(message, inner) { }
protected InvalidExampleException(System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
如Microsoft Docs中所述,c#中的异常至少需要这四个构造函数。
然后,只需在代码中使用此异常,即可:
using InvalidExampleException;
public class test
{
public int i = 0;
public void check_i()
{
if (i == 0) // if i = 0: error
{
// exception
throw new InvalidExampleException("Index is zero");
}
}
}
答案 6 :(得分:0)
您可以使用“ Exception”类作为基类来创建自定义异常
public class TestCustomException: Exception
{
public TestCustomException(string message, Exception inner)
: base(message, inner)
{
}
}
完整的控制台示例
class TestCustomException : Exception
{
public TestCustomException(string message) : base(message)
{
this.HelpLink = "Sample Link details related to error";
this.Source = "This is source of Error";
}
}
class MyClass
{
public static void Show()
{
throw new TestCustomException("This is Custom Exception example in C#");
}
}
class Program
{
static void Main(string[] args)
{
try
{
MyClass.Show();
}
catch (TestCustomException ex)
{
Console.WriteLine("Error Message:-" + ex.Message);
Console.WriteLine("Hyper Link :-" + ex.HelpLink);
Console.WriteLine("Source :- " + ex.Source);
Console.ReadKey();
}
}
}
来源:Creating C# Custom Exception (With Console application example)
答案 7 :(得分:-3)
您可以定义自己的例外。
用户定义的异常类派生自ApplicationException类。
您可以看到以下代码:
using System;
namespace UserDefinedException
{
class TestTemperature
{
static void Main(string[] args)
{
Temperature temp = new Temperature();
try
{
temp.showTemp();
}
catch(TempIsZeroException e)
{
Console.WriteLine("TempIsZeroException: {0}", e.Message);
}
Console.ReadKey();
}
}
}
public class TempIsZeroException: ApplicationException
{
public TempIsZeroException(string message): base(message)
{
}
}
public class Temperature
{
int temperature = 0;
public void showTemp()
{
if(temperature == 0)
{
throw (new TempIsZeroException("Zero Temperature found"));
}
else
{
Console.WriteLine("Temperature: {0}", temperature);
}
}
}
并且抛出异常,
如果对象直接或间接来自System.Exception类
,则可以抛出该对象Catch(Exception e)
{
...
Throw e
}