在C#中,我如何定义自己的异常?
在C#中,如何定义自己的异常?在C#中,我如何定义自己的异常?,c#,exception,C#,Exception,在C#中,如何定义自己的异常? 看来我已经开始了一场有点例外的分包战斗。根据您遵循的Microsoft最佳实践指南,您可以从System.Exception或System.ApplicationException继承。有一篇很好(但很旧)的博客文章试图澄清这一困惑。现在我将保留我的示例,但您可以阅读本文并根据需要进行选择: 不再有战斗了!感谢Frederik指出FxCop规则CA1058,该规则规定您的异常应继承自System.Exception而非System.ApplicationExce
看来我已经开始了一场有点例外的分包战斗。根据您遵循的Microsoft最佳实践指南,您可以从System.Exception或System.ApplicationException继承。有一篇很好(但很旧)的博客文章试图澄清这一困惑。现在我将保留我的示例,但您可以阅读本文并根据需要进行选择: 不再有战斗了!感谢Frederik指出FxCop规则CA1058,该规则规定您的异常应继承自System.Exception而非System.ApplicationException:
定义一个从Exception继承的新类(我已经包含了一些构造函数…但您不必拥有它们): 以及代码中要抛出的其他内容:
throw new MyException("My message here!");
编辑 已使用更改进行更新,以确保可序列化异常。详情可在此找到: 请密切关注有关向异常类添加自定义属性时需要采取的步骤的部分。 谢谢伊戈尔打电话给我 要定义:
public class SomeException : Exception
{
// Add your own constructors and properties here.
}
投掷:
throw new SomeException();
定义:
public class CustomException : Exception
{
public CustomException(string Message) : base (Message)
{
}
}
投掷:
throw new CustomException("Custom exception message");
创建自己的异常的指导原则(紧挨着类应该从异常继承的事实)
- 通过添加
属性,确保类是可序列化的[serializable]
- 提供异常使用的公共构造函数:
MyException (); MyException (string message); MyException (string message, Exception innerException);
异常
至少应如下所示:
[Serializable]
public class MyException : Exception
{
public MyException ()
{}
public MyException (string message)
: base(message)
{}
public MyException (string message, Exception innerException)
: base (message, innerException)
{}
}
关于是否应从异常
或应用程序异常
继承的事实:
FxCop有一条规则,规定您应避免继承自ApplicationException
:
CA1058:Microsoft.Design:改变 “MyException”的基类型,以便 它不再延伸 “ApplicationException”。这个基地 异常类型不提供任何 框架的附加值 上课。扩展“System.Exception”或 现有的未密封异常类型 相反不要创建新的异常 基类型,除非有特定的 在创建 整个类的捕获处理程序 例外情况
请参阅有关此规则的信息。您可以定义自己的异常 用户定义的异常类派生自该类 您可以看到以下代码:
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);
}
}
}
以及抛出一个异常
如果对象直接或间接派生自类,则可以抛出该对象
来自微软的:
要定义自己的异常类,请执行以下操作:
- 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 );
}
投掷中的用法:
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 );
}
在try/catch中的用法:
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 );
}
要创建自己的异常,可以使用以下示例:
[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) { }
}
如中所述,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");
}
}
}
您可以使用“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();
}
}
}
资料来源:感谢您(但不是+1)以尽可能少的字数提出了一个易懂的问题。我同意下面的所有答案,但希望指出您应该始终直接从System.ApplicationException继承。MS对此的指导方针是立即区分系统异常和用户定义的异常。无论您选择哪一个,都要编写基类并保持异常用法的一致性。@Joel-说话要小心。Microsoft最佳实践文档在自定义例外方面自相矛盾。我改变了答案,因为OP的使用似乎更倾向于应用程序异常。查看这篇关于矛盾的帖子:@Justin Niessner:如果你想在AppDomain中抛出自定义异常,就必须使其可序列化。不建议从ApplicationException继承。它毫无理由地增加了继承层次结构。请参见和@Gabe Moothart:“您可以避免与自定义属性和序列化相关的麻烦”--仅当您的自定义属性