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博客。

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