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

目录
相关文章
|
3月前
|
存储 安全 编译器
C# 11.0中的泛型属性:类型安全的新篇章
【1月更文挑战第23天】C# 11.0引入了泛型属性的概念,这一新特性为开发者提供了更高级别的类型安全性和灵活性。本文将详细探讨C# 11.0中泛型属性的工作原理、使用场景以及它们对现有编程模式的改进。通过深入了解泛型属性,开发者将能够编写更加健壮、可维护的代码,并充分利用C#语言的最新发展。
|
6月前
|
关系型数据库 MySQL C#
C# winform 一个窗体需要调用自定义用户控件的控件名称
给用户控件ucQRCode增加属性: //二维码图片 private PictureBox _pictureBoxFSHLQrCode; public PictureBox PictureBoxFSHLQrCode {   get { return _pictureBoxFSHLQrCode; }   set { this.pictureBoxFSHLQrCode = value; } } 在Form1窗体直接调用即可: ucQRCode uQRCode=new ucQRCode(); ucQRCode.PictureBoxFSHLQrCode.属性= 要复制或传给用户控件上的控件的值
36 0
|
7月前
|
编译器 C#
C#之十七 局部类型
C#之十七 局部类型
17 0
|
1月前
|
C#
C#学习相关系列之自定义遍历器
C#学习相关系列之自定义遍历器
|
1月前
|
存储 C# 开发者
C#变量类型
C#变量类型
19 0
|
7月前
|
编译器 C#
c# 自定义扩展方法
c# 自定义扩展方法
|
3月前
|
开发框架 .NET 编译器
C# 9.0中的目标类型新表达式:类型推断的又一进步
【1月更文挑战第16天】C# 9.0引入了目标类型新表达式,这是类型推断功能的一个重要扩展。通过目标类型新表达式,开发者在创建对象时可以省略类型名称,编译器会根据上下文自动推断所需类型。这一特性不仅简化了代码编写,还提高了代码的可读性和维护性。本文将详细介绍目标类型新表达式的语法、使用场景及其对C#编程的影响。
|
3月前
|
存储 C# 容器
掌握 C# 变量:在代码中声明、初始化和使用不同类型的综合指南
变量是用于存储数据值的容器。 在 C# 中,有不同类型的变量(用不同的关键字定义),例如: int - 存储整数(没有小数点的整数),如 123 或 -123 double - 存储浮点数,有小数点,如 19.99 或 -19.99 char - 存储单个字符,如 'a' 或 'B'。Char 值用单引号括起来 string - 存储文本,如 "Hello World"。String 值用双引号括起来 bool - 存储具有两个状态的值:true 或 false
37 2
|
3月前
|
存储 安全 算法
C# 泛型:类型参数化的强大工具
【1月更文挑战第7天】本文将深入探讨C#语言中的泛型编程,包括泛型的定义、用途、优势以及实际应用。通过类型参数化,泛型允许开发者编写更加灵活且可重用的代码,同时提高程序的类型安全性和性能。本文将通过示例代码和详细解释,帮助读者更好地理解泛型在C#中的重要性和实用性。
|
4月前
|
存储 Java C#
【从Java转C#】第七章:运算符和类型强制转换
【从Java转C#】第七章:运算符和类型强制转换