2021年3月25日星期四

Why define a custom exception with a specified TExceptionArgs?

I am reading the CLR via C# book, the author shows how to define custom exception as:

class Program {     static void Main(string[] args) {        TestException();     }       static void TestException() {        try {           throw new Exception<DiskFullExceptionArgs>(new DiskFullExceptionArgs(@"C:\"), "The disk is full");        }        catch (Exception<DiskFullExceptionArgs> e) {           Console.WriteLine(e.Message);          }     }  }    [Serializable]  public sealed class DiskFullExceptionArgs : ExceptionArgs {     private readonly String m_diskpath;   // private field set at construction time       public DiskFullExceptionArgs(String diskpath) {        m_diskpath = diskpath;     }       public String DiskPath { get { return m_diskpath; } }       // Override the Message property to include our field (if set)     public override String Message {        get {           return (m_diskpath == null) ? base.Message : "DiskPath=" + m_diskpath;        }     }  }    [Serializable]  public abstract class ExceptionArgs {     public virtual String Message { get { return String.Empty; } }  }    [Serializable]  public sealed class Exception<TExceptionArgs> : Exception, ISerializable where TExceptionArgs : ExceptionArgs {     private const String c_args = "Args";   // For (de)serialization     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;     }       // This constructor is for deserialization; since the class is sealed, the constructor is     // private. If this class were not sealed, this constructor should be protected     [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]     private Exception(SerializationInfo info, StreamingContext context) : base(info, context) {        m_args = (TExceptionArgs)info.GetValue(c_args, typeof(TExceptionArgs));     }       // This method is for serialization; it's public because of the ISerializable interface     [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) ? baseMsg : baseMsg + " (" + m_args.Message + ")";          }     }       public override Boolean Equals(Object obj) {        Exception<TExceptionArgs> other = obj as Exception<TExceptionArgs>;        if (other == null)           return false;        return Object.Equals(m_args, other.m_args) && base.Equals(obj);     }     public override int GetHashCode() { return base.GetHashCode(); }  }  

I have two questions:

Q1-Whats the benefit to define a custom exception args ExceptionArgs and create a concrete DiskFullExceptionArgs? From my understanding, you can just pass a whole message "The disk is full C:" to the custom exception, why separate "C:" into ExceptionArgs and "The disk is full" to the custom exception?

Q2- This custom exception overwrite Equals methods. But why you need to compare two Exception instance? I don't see any scenarios that requires to compare two exception instances

https://stackoverflow.com/questions/66810822/why-define-a-custom-exception-with-a-specified-texceptionargs March 26, 2021 at 11:53AM

没有评论:

发表评论