在 C# 中如何定义自己的异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2200241/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In C# how do I define my own Exceptions?
提问by
In C# how do I define my own Exceptions?
在 C# 中如何定义自己的异常?
回答by Justin Niessner
It seems that I've started a bit of an Exception sublcassing battle. Depending on the Microsoft Best Practices guide you follow...you can either inherit from System.Exception or System.ApplicationException. There's a good (but old) blog post that tries to clear up the confusion. I'll keep my example with Exception for now, but you can read the post and chose based on what you need:
似乎我已经开始了一些异常 sublcassing 战。根据您遵循的 Microsoft 最佳实践指南...您可以从 System.Exception 或 System.ApplicationException 继承。有一篇很好(但很旧)的博客文章试图消除混淆。我现在将使用 Exception 保留我的示例,但您可以阅读这篇文章并根据需要进行选择:
http://weblogs.asp.net/erobillard/archive/2004/05/10/129134.aspx
http://weblogs.asp.net/erobillard/archive/2004/05/10/129134.aspx
There is a battle no more! Thanks to Frederik for pointing out FxCop rule CA1058 which states that your Exceptions should inherit from System.Exception rather than System.ApplicationException:
没有战斗了!感谢 Frederik 指出 FxCop 规则 CA1058,该规则指出您的异常应继承自 System.Exception 而不是 System.ApplicationException:
CA1058: Types should not extend certain base types
Define a new class that inherits from Exception (I've included some Constructors...but you don't have to have them):
定义一个从 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)
{ }
}
And elsewhere in your code to throw:
并在您的代码中的其他地方抛出:
throw new MyException("My message here!");
EDIT
编辑
Updated with changes to ensure a Serializable Exception. Details can be found here:
更新了更改以确保可序列化异常。详细信息可以在这里找到:
Winterdom Blog Archive - Make Exception Classes Serializable
Pay close attention to the section about steps that need to be taken if you add custom Properties to your Exception class.
请密切注意有关将自定义属性添加到 Exception 类时需要采取的步骤的部分。
Thanks to Igor for calling me on it!
感谢 Igor 给我打电话!
回答by Will Vousden
To define:
界定:
public class SomeException : Exception
{
// Add your own constructors and properties here.
}
To throw:
扔:
throw new SomeException();
回答by SimpleButPerfect
Definition:
定义:
public class CustomException : Exception
{
public CustomException(string Message) : base (Message)
{
}
}
throwing:
投掷:
throw new CustomException("Custom exception message");
回答by Frederik Gheysels
Guidelines for creating your own exception (next to the fact that your class should inherit from exception)
创建您自己的异常的指南(在您的类应该从异常继承这一事实旁边)
- make sure the class is serializable, by adding the
[Serializable]
attribute provide the common constructors that are used by exceptions:
MyException (); MyException (string message); MyException (string message, Exception innerException);
- 通过添加
[Serializable]
属性确保该类是可序列化的 提供异常使用的公共构造函数:
MyException (); MyException (string message); MyException (string message, Exception innerException);
So, ideally, your custom Exception
should look at least like this:
因此,理想情况下,您的自定义Exception
至少应如下所示:
[Serializable]
public class MyException : Exception
{
public MyException ()
{}
public MyException (string message)
: base(message)
{}
public MyException (string message, Exception innerException)
: base (message, innerException)
{}
}
About the fact whether you should inherit from Exception
or ApplicationException
:
FxCop has a rule which says you should avoid inheriting from ApplicationException
:
关于您是否应该继承Exception
或的事实ApplicationException
:FxCop 有一条规则说您应该避免继承自ApplicationException
:
CA1058 : Microsoft.Design :
Change the base type of 'MyException' so that it no longer extends 'ApplicationException'. This base exception type does not provide any additional value for framework classes. Extend 'System.Exception' or an existing unsealed exception type instead. Do not create a new exception base type unless there is specific value in enabling the creation of a catch handler for an entire class of exceptions.
CA1058:Microsoft.Design:
更改“MyException”的基类型,使其不再扩展“ApplicationException”。此基本异常类型不为框架类提供任何附加值。改为扩展“System.Exception”或现有的未密封异常类型。不要创建新的异常基类型,除非在为整个异常类启用捕获处理程序的创建中有特定的价值。
See the page on MSDNregarding this rule.
有关此规则,请参阅MSDN 上的页面。
回答by Vivek Saurav
You can define your own exception.
您可以定义自己的异常。
User-defined exception classes are derived from the ApplicationExceptionclass.
用户定义的异常类派生自ApplicationException类。
You can see the following code:
您可以看到以下代码:
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);
}
}
}
and for throwing an exception,
并抛出异常,
You can throw an object if it is either directly or indirectly derived from the System.Exceptionclass
如果对象直接或间接派生自System.Exception类,则可以抛出该对象
Catch(Exception e)
{
...
Throw e
}
回答by Jpsy
From Microsoft's .NET Core 3.0 docs:
来自 Microsoft 的.NET Core 3.0 文档:
To define your own exception class:
要定义您自己的异常类:
Define a class that inherits from Exception. If necessary, define any unique members needed by your class to provide additional information about the exception. For example, the ArgumentException class includes a ParamName property that specifies the name of the parameter whose argument caused the exception, and the RegexMatchTimeoutException property includes a MatchTimeout property that indicates the time-out interval.
If necessary, override any inherited members whose functionality you want to change or modify. Note that most existing derived classes of Exception do not override the behavior of inherited members.
Determine whether your custom exception object is serializable. Serialization enables you to save information about the exception and permits exception information to be shared by a server and a client proxy in a remoting context. To make the exception object serializable, mark it with the SerializableAttribute attribute.
Define the constructors of your exception class. Typically, exception classes have one or more of the following constructors:
Exception(), which uses default values to initialize the properties of a new exception object.
Exception(String), which initializes a new exception object with a specified error message.
Exception(String, Exception), which initializes a new exception object with a specified error message and inner exception.
Exception(SerializationInfo, StreamingContext), which is a protected constructor that initializes a new exception object from serialized data. You should implement this constructor if you've chosen to make your exception object serializable.
定义一个继承自 Exception 的类。如有必要,定义您的类所需的任何唯一成员,以提供有关异常的其他信息。例如,ArgumentException 类包含一个 ParamName 属性,该属性指定其参数导致异常的参数的名称,而 RegexMatchTimeoutException 属性包含一个 MatchTimeout 属性,该属性指示超时间隔。
如有必要,覆盖要更改或修改其功能的任何继承成员。请注意,大多数现有的 Exception 派生类不会覆盖继承成员的行为。
确定您的自定义异常对象是否可序列化。序列化使您能够保存有关异常的信息,并允许服务器和客户端代理在远程处理上下文中共享异常信息。要使异常对象可序列化,请使用 SerializableAttribute 属性对其进行标记。
定义异常类的构造函数。通常,异常类具有以下一个或多个构造函数:
Exception(),它使用默认值来初始化新异常对象的属性。
Exception(String),用指定的错误信息初始化一个新的异常对象。
Exception(String, Exception),它用指定的错误消息和内部异常初始化一个新的异常对象。
Exception(SerializationInfo, StreamingContext),它是一个受保护的构造函数,用于从序列化数据初始化一个新的异常对象。如果您选择使异常对象可序列化,则应该实现此构造函数。
Example:
例子:
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)
{ }
}
Usage in throw:
投掷中的用法:
throw new NotPrimeException(prime, "This is not a prime number."));
Usage in try/catch:
在 try/catch 中的用法:
try
{
...
}
catch (NotPrimeException e)
{
Console.WriteLine( "{0} is not prime", e.NotAPrime );
}
回答by Adam Perea
To create your own exception, you can go with this example:
要创建自己的异常,您可以使用以下示例:
[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) { }
}
As said in Microsoft Docs, an exception in c# needs at least those four constructors.
如Microsoft Docs所述,c# 中的异常至少需要这四个构造函数。
Then, to use this exception in your code, you just have to do:
然后,要在您的代码中使用此异常,您只需执行以下操作:
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");
}
}
}