C# 自定义异常类型(摘自CLR Via C# 3th Edition)

简介:

ExceptionArgs.cs:

//异常信息基类 [Serializable] public abstract class ExceptionArgs { public virtual String Message { get { return String.Empty; } } }

泛型的异常类:

[Serializable] public sealed class Exception<TExceptionArgs>:Exception,System.Runtime.Serialization.ISerializable where TExceptionArgs:ExceptionArgs{ private const String c_args = "Args"; private readonly TExceptionArgs m_args; public TExceptionArgs Args { get { return m_args; } } public Exception(string message = null, Exception innerException = null) : this(null, message, innerException) { } public Exception(TExceptionArgs args, String message = null, Exception innerException = null) : base(message, innerException) { m_args = args; } //该构造器用于反序列化,由于类是密封的,所以构造器是私有的 //如果类不是密封的,这个构造器就应该是受保护的 [SecurityPermission(SecurityAction.LinkDemand,Flags=SecurityPermissionFlag.SerializationFormatter)] private Exception(SerializationInfo info,StreamingContext context) :base(info,context){ m_args = (TExceptionArgs)info.GetValue(c_args, typeof(TExceptionArgs)); } //这个方法用于序列化,由于实现了ISerializable接口,所以它是公共的(该方法为ISerializable中定义的方法) //在Exception类中已有实现,此类继承了Exception,并重写了该方法在Exception中的实现 [SecurityPermission(SecurityAction.LinkDemand,Flags=SecurityPermissionFlag.SerializationFormatter)] public override void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue(c_args, m_args); base.GetObjectData(info, context); } public override string Message { get { String baseMsg = base.Message; return (m_args == null) ? base.Message : baseMsg + "(" + m_args.Message + ")"; } } public override bool Equals(object obj) { Exception<TExceptionArgs> other = obj as Exception<TExceptionArgs>; if (obj==null) { return false; } return Object.ReferenceEquals(m_args, other.m_args) && base.Equals(obj); } public override int GetHashCode() { return base.GetHashCode(); } }

注:C#只允许自定义的类继承自系统异常类的基类:System.Exception,并且继承自System.Exception类的所有异常类型,都必须是可被序列化的,这使得这些异常信息得以穿越AppDomain(比如Remoting服务端异常有可能需要返回到远程调用方,这时就不得不穿越AppDomain)或者写入日志/数据库等。

定义一个磁盘满的异常类:

//定义一个磁盘满的异常类 [Serializable] public sealed class DiskFullExceptionArgs:ExceptionArgs { //readonly:只读,动态常量,只能在构造器中被赋值 private readonly String m_diskpath; public DiskFullExceptionArgs(String diskpath) { m_diskpath = diskpath; } public String DiskPath { get { return m_diskpath; } } public override string Message { get { return (m_diskpath == null) ? base.Message : "DiskPath=" + m_diskpath; } } }

如果没有额外的数据要包含到类中,可以简单地写:

//定义一个磁盘满的异常类 [Serializable] public sealed class DiskFullExceptionArgs:ExceptionArgs { }

抛出/捕获自定义异常:

public void TestException() { try { throw new Exception<DiskFullExceptionArgs>( new DiskFullExceptionArgs(@"C:/"), "The disk is full"); } catch (Exception<DiskFullExceptionArgs> ex) { Console.WriteLine(ex.Message); } }





原文发布时间为:2011-02-05


本文作者:vinoYang


本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。

目录
相关文章
|
18天前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
27 3
|
17天前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
34 1
|
5月前
|
C# C++
C# 自定义时间进度条
本文作者通过参考leslie_xin的一篇文章,成功创建了一个自定义的WinForms控件——时间进度条,该控件带有时间刻度和多种可定制的属性,如颜色、时间间隔等。作者在控件中加入了开始和结束时间,以及自适应的时间刻度间隔。控件能根据设置显示时间标签,并提供了事件处理,如值改变时的触发。代码中包含了计算时间刻度、绘制刻度线和时间标签的逻辑。作者强调了避免循环调用事件、使用OnXXX()形式的事件处理函数以及注意自定义控件中的属性和事件设计。
132 7
|
16天前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
9 0
|
1月前
|
C#
C# 可空类型(Nullable)
C# 单问号 ? 与 双问号 ??
46 12
|
3月前
|
安全 测试技术 数据库连接
如何避免 C# 中的异常
【8月更文挑战第27天】
50 2
|
3月前
|
开发框架 .NET 编译器
总结一下 C# 如何自定义特性 Attribute 并进行应用
总结一下 C# 如何自定义特性 Attribute 并进行应用
|
3月前
|
存储 C#
揭秘C#.Net编程秘宝:结构体类型Struct,让你的数据结构秒变高效战斗机,编程界的新星就是你!
【8月更文挑战第4天】在C#编程中,结构体(`struct`)是一种整合多种数据类型的复合数据类型。与类不同,结构体是值类型,意味着数据被直接复制而非引用。这使其适合表示小型、固定的数据结构如点坐标。结构体默认私有成员且不可变,除非明确指定。通过`struct`关键字定义,可以包含字段、构造函数及方法。例如,定义一个表示二维点的结构体,并实现计算距离原点的方法。使用时如同普通类型,可通过实例化并调用其成员。设计时推荐保持结构体不可变以避免副作用,并注意装箱拆箱可能导致的性能影响。掌握结构体有助于构建高效的应用程序。
111 7
|
3月前
|
程序员 C#
C# 语言类型全解
C# 语言类型全解
25 0