Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   Defining Your Own Exception Class

Unfortunately, designing your own exception is tedious and error prone. The main reason for this is because all Exception-derived types should be serializable so that they can cross an AppDomain boundary or be written to a log or database. There are many issues related to serialization and they are discussed in Chapter 24, “Runtime Serialization.” So, in an effort to simplify things, I made my own generic Exception<TExceptionArgs> class, which is defined as follows.

 

[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(); }

}

 

And the ExceptionArgs base class that TExceptionArgs is constrained to is very simple and looks like this.

 

[Serializable]

public abstract class ExceptionArgs {

public virtual String Message { get { return String.Empty; } }

}

 

Now, with these two classes defined, I can trivially define more exception classes when I need to.

To define an exception type indicating the disk is full, I simply do the following.

 

[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 read­only property that returns the field 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;

}

}

}

 

And, if I have no additional data that I want to put inside the class, it gets as simple as the following.

 

[Serializable]

public sealed class DiskFullExceptionArgs : ExceptionArgs { }


And now I can write code like this, which throws and catches one of these.

 

public static void TestException() { try {

throw new Exception<DiskFullExceptionArgs>(

new DiskFullExceptionArgs(@"C:\"), "The disk is full");

}

catch (Exception<DiskFullExceptionArgs> e) { Console.WriteLine(e.Message);

}

}

       
   
 
 

 

 


Date: 2016-03-03; view: 678


<== previous page | next page ==>
Nbsp;   Throwing an Exception | Nbsp;   Trading Reliability for Productivity
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.008 sec.)