Tải bản đầy đủ - 0 (trang)
13-8. Implement a Custom Exception Class

13-8. Implement a Custom Exception Class

Tải bản đầy đủ - 0trang

CHAPTER 13 ■ COMMONLY USED INTERFACES AND PATTERNS







System.FormatException, when code attempts to pass your method a String

argument containing incorrectly formatted data



If none of the existing exception classes meet your needs, or you feel your application would benefit

from using application-specific exceptions, it’s a simple matter to create your own exception class. In

order to integrate your custom exception with the runtime’s exception-handling mechanism and remain

consistent with the pattern implemented by .NET Framework–defined exception classes, you should do

the following:





Give your exception class a meaningful name ending in the word Exception, such

as TypeMismatchException or RecordNotFoundException.







Mark your exception class as sealed if you do not intend other exception classes to

extend it.







Implement additional data members and properties to support custom

information that the exception class should provide.







Implement three public constructors with the signatures shown here and ensure

that they call the base class constructor:

public CustomException() : base() {}

public CustomException(string msg): base(msg) {}

public CustomException(string msg, Exception inner) : base(msg, inner) {}







Make your exception class serializable so that the runtime can marshal instances

of your exception across application domain and machine boundaries. Applying

the attribute System.SerializableAttribute is sufficient for exception classes that

do not implement custom data members. However, because Exception

implements the interface System.Runtime.Serialization.ISerializable, if your

exception declares custom data members, you must override the

ISerializable.GetObjectData method of the Exception class as well as implement

a deserialization constructor with this signature. If your exception class is sealed,

mark the deserialization constructor as private; otherwise, mark it as protected.

The GetObjectData method and deserialization constructor must call the

equivalent base class method to allow the base class to serialize and deserialize its

data correctly. (See recipe 13-1 for details on making classes serializable.)



■ Tip In large applications, you will usually implement quite a few custom exception classes. It pays to put

significant thought into how you organize your custom exceptions and how code will use them. Generally, avoid

creating new exception classes unless code will make specific efforts to catch that exception; use data members

to achieve informational granularity, not additional exception classes. In addition, avoid deep class hierarchies

when possible in favor of broad, shallow hierarchies.



656



www.it-ebooks.info



CHAPTER 13 ■ COMMONLY USED INTERFACES AND PATTERNS



The Code

The following example is a custom exception named CustomException that extends Exception and

declares two custom data members: a string named stringInfo and a bool named booleanInfo.

using System;

using System.Runtime.Serialization;

namespace Apress.VisualCSharpRecipes.Chapter13

{

// Mark CustomException as Serializable.

[Serializable]

public sealed class CustomException : Exception

{

// Custom data members for CustomException.

private string stringInfo;

private bool booleanInfo;

// Three standard constructors and simply call the base class.

// constructor (System.Exception).

public CustomException() : base() { }

public CustomException(string message) : base(message) { }

public CustomException(string message, Exception inner)

: base(message, inner) { }

// The deserialization constructor required by the ISerialization

// interface. Because CustomException is sealed, this constructor

// is private. If CustomException were not sealed, this constructor

// should be declared as protected so that derived classes can call

// it during deserialization.

private CustomException(SerializationInfo info,

StreamingContext context) : base(info, context)

{

// Deserialize each custom data member.

stringInfo = info.GetString("StringInfo");

booleanInfo = info.GetBoolean("BooleanInfo");

}

// Additional constructors to allow code to set the custom data

// members.

public CustomException(string message, string stringInfo,

bool booleanInfo) : this(message)

{

this.stringInfo = stringInfo;

this.booleanInfo = booleanInfo;

}



657



www.it-ebooks.info



CHAPTER 13 ■ COMMONLY USED INTERFACES AND PATTERNS



public CustomException(string message, Exception inner,

string stringInfo, bool booleanInfo): this(message, inner)

{

this.stringInfo = stringInfo;

this.booleanInfo = booleanInfo;

}

// Read-only properties that provide access to the custom data members.

public string StringInfo

{

get { return stringInfo; }

}

public bool BooleanInfo

{

get { return booleanInfo; }

}

// The GetObjectData method (declared in the ISerializable interface)

// is used during serialization of CustomException. Because

// CustomException declares custom data members, it must override the

// base class implementation of GetObjectData.

public override void GetObjectData(SerializationInfo info,

StreamingContext context)

{

// Serialize the custom data members.

info.AddValue("StringInfo", stringInfo);

info.AddValue("BooleanInfo", booleanInfo);

// Call the base class to serialize its members.

base.GetObjectData(info, context);

}

// Override the base class Message property to include the custom data

// members.

public override string Message

{

get

{

string message = base.Message;

if (stringInfo != null)

{

message += Environment.NewLine +

stringInfo + " = " + booleanInfo;

}

return message;

}

}

}



658



www.it-ebooks.info



CHAPTER 13 ■ COMMONLY USED INTERFACES AND PATTERNS



// A class to demonstrate the use of CustomException.

public class Recipe13_08

{

public static void Main()

{

try

{

// Create and throw a CustomException object.

throw new CustomException("Some error",

"SomeCustomMessage", true);

}

catch (CustomException ex)

{

Console.WriteLine(ex.Message);

}

// Wait to continue.

Console.WriteLine(Environment.NewLine);

Console.WriteLine("Main method complete. Press Enter");

Console.ReadLine();

}

}

}



13-9. Implement a Custom Event Argument

Problem

When you raise an event, you need to pass an event-specific state to the event handlers.



Solution

Create a custom event argument class derived from the System.EventArg class. When you raise the event,

create an instance of your event argument class and pass it to the event handlers.



How It Works

When you declare your own event types, you will often want to pass event-specific state to any listening

event handlers. To create a custom event argument class that complies with the Event pattern defined

by the .NET Framework, you should do the following:





Derive your custom event argument class from the EventArgs class. The EventArgs

class contains no data and is used with events that do not need to pass event state.







Give your event argument class a meaningful name ending in EventArgs, such as

DiskFullEventArgs or MailReceivedEventArgs.



659



www.it-ebooks.info



CHAPTER 13 ■ COMMONLY USED INTERFACES AND PATTERNS







Mark your argument class as sealed if you do not intend other event argument

classes to extend it.







Implement additional data members and properties that you need to pass to

event handlers to support event state. It’s best to make event state immutable, so

you should use private readonly data members and public properties to provide

read-only access to the data members.







Implement a public constructor that allows you to set the initial configuration of

the event state.







Make your event argument class serializable so that the runtime can marshal

instances of it across application domain and machine boundaries. Applying the

attribute System.SerializableAttribute is usually sufficient for event argument

classes. However, if your class has special serialization requirements, you must

also implement the interface System.Runtime.Serialization.ISerializable. (See

recipe 13-1 for details on making classes serializable.)



The Code

The following example demonstrates the implementation of an event argument class named

MailReceivedEventArgs. Theoretically, an e-mail server passes instances of the MailReceivedEventArgs

class to event handlers in response to the receipt of an e-mail message. The MailReceivedEventArgs class

contains information about the sender and subject of the received e-mail message.

using System;

namespace Apress.VisualCSharpRecipes.Chapter13

{

[Serializable]

public sealed class MailReceivedEventArgs : EventArgs

{

// Private read-only members that hold the event state that is to be

// distributed to all event handlers. The MailReceivedEventArgs class

// will specify who sent the received mail and what the subject is.

private readonly string from;

private readonly string subject;

// Constructor, initializes event state.

public MailReceivedEventArgs(string from, string subject)

{

this.from = from;

this.subject = subject;

}

// Read-only properties to provide access to event state.

public string From { get { return from; } }

public string Subject { get { return subject; } }

}



660



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

13-8. Implement a Custom Exception Class

Tải bản đầy đủ ngay(0 tr)

×