Seien Sie vorsichtig bei der Verwendung eingebauter Ausnahmetypen... sie haben sehr spezifische Bedeutungen für das .NET-Framework, und wenn Sie sie nicht für genau die gleiche Bedeutung haben, ist es besser, selbst zu würfeln (+1 an John Saunders für Serializeable
).
InvalidOperationException
hat die Bedeutung:
Die Ausnahme, die ausgelöst wird, wenn ein Methodenaufruf für den aktuellen Zustand des Objekts ungültig ist.
Wenn Sie zum Beispiel SqlConnection.Open()
erhalten Sie eine InvalidOperationException
wenn Sie keine Datenquelle angegeben haben. InvalidOperationException
ist für Ihr Szenario nicht geeignet.
ArgumentException
ist auch nicht angebracht. Das Versäumnis, eine objectOfAnotherClass
hat möglicherweise nichts mit der Übermittlung fehlerhafter Daten zu tun. Angenommen, es ist ein Dateiname, aber GetObject()
keine Berechtigung hat, die Datei zu lesen. So wie die Methode geschrieben ist, gibt es keine Möglichkeit zu wissen, warum der Aufruf von GetObject()
fehlgeschlagen, und Sie können höchstens sagen, dass das zurückgegebene Objekt null oder ungültig war.
Exception
ist einfach eine schlechte Idee, im Allgemeinen ... es gibt dem Aufrufer absolut keine Ahnung, warum die Methode das Objekt erstellen fehlgeschlagen. (Im Übrigen, wenn man nur eine catch (Exception ex) {..}
ist auch eine schlechte Idee)
Sie wollen Ausnahmen, die klar erkennen lassen, was schief gelaufen ist, und das bedeutet, dass Sie Ihre eigenen Ausnahmen erstellen müssen. Versuchen Sie, diese allgemein zu halten, um 1.000 benutzerdefinierte Ausnahmen zu vermeiden. Ich schlage vor:
ObjectCreateException: // The call to GetObject() returned null<br />
InvalidObjectException: // The object returned by GetObject() is invalid
// (because the property < 0)
Danke für das Votum ~ ich dachte, ich füge ein Beispiel für einige benutzerdefinierte Ausnahmen hinzu, die wir geschrieben haben.
Beachten Sie, dass Sie den Methoden keinen Code hinzufügen müssen, da die benutzerdefinierten Ausnahmen nicht wirklich etwas anderes tun als ihre Basisklassen; sie stellen nur etwas anderes dar. Das zweite Beispiel fügt der Ausnahme eine Eigenschaft hinzu, so dass es Code gibt, um sie zu unterstützen (einschließlich Konstruktoren).
Die erste ist eine generische Basis für alle unsere Ausnahmen; es gilt die Regel "Don't catch general Exceptions" (obwohl wir es trotzdem tun... es erlaubt uns, zwischen den von uns generierten Ausnahmen und den vom Framework ausgelösten Ausnahmen zu unterscheiden). Die zweite ist eine spezifischere Ausnahme, die sich ableitet von Gs3Exception
und serialisiert eine benutzerdefinierte Eigenschaft.
Das .NET-Entwicklungsteam beschloss ApplicationException
hatte keinen realen Wert und wurde abgeschafft, aber der Purist in mir mochte es schon immer, also wird es in meinem Code beibehalten. In diesem Fall bringt es jedoch wirklich keinen Mehrwert und erhöht nur die Tiefe der Vererbungshierarchie. Es steht Ihnen also frei, direkt zu erben von Exception
stattdessen.
/// <summary>
/// A general, base error for GS3 applications </summary>
[Serializable]
public class Gs3Exception : ApplicationException {
/// <summary>
/// Initializes a new instance of the <see cref="Gs3Exception"/> class </summary>
public Gs3Exception() {}
/// <summary>
/// Initializes a new instance of the <see cref="Gs3Exception"/> class </summary>
/// <param name="message">A brief, descriptive message about the error </param>
public Gs3Exception(string message) : base(message) {}
/// <summary>
/// Initializes a new instance of the <see cref="Gs3Exception"/> class
/// when deserializing </summary>
/// <param name="info">The object that holds the serialized object data </param>
/// <param name="context">The contextual information about the source or
/// destination.</param>
public Gs3Exception(SerializationInfo info, StreamingContext context) : base(info, context) { }
/// <summary>
/// Initializes a new instance of the <see cref="Gs3Exception"/> class
/// with a message and inner exception </summary>
/// <param name="Message">A brief, descriptive message about the error </param>
/// <param name="exc">The exception that triggered the failure </param>
public Gs3Exception(string Message, Exception exc) : base(Message, exc) { }
}
/// <summary>
/// An object queried in an request was not found </summary>
[Serializable]
public class ObjectNotFoundException : Gs3Application {
private string objectName = string.Empty;
/// <summary>
/// Initializes a new instance of the <see cref="ObjectNotFoundException"/> class </summary>
public ObjectNotFoundException() {}
/// <summary>
/// Initializes a new instance of the <see cref="ObjectNotFoundException"/> class </summary>
/// <param name="message">A brief, descriptive message about the error</param>
public ObjectNotFoundException(string message) : base(message) {}
/// <summary>
/// Initializes a new instance of the <see cref="ObjectNotFoundException"/> class </summary>
/// <param name="ObjectName">Name of the object not found </param>
/// <param name="message">A brief, descriptive message about the error </param>
public ObjectNotFoundException(string ObjectName, string message) : this(message) {
this.ObjectName = ObjectName;
}
/// <summary>
/// Initializes a new instance of the <see cref="ObjectNotFoundException"/> class.
/// This method is used during deserialization to retrieve properties from
/// the serialized data. </summary>
/// <param name="info">The object that holds the serialized object data.</param>
/// <param name="context">The contextual information about the source or
/// destination.</param>
public ObjectNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) {
if (null != info) {
this.objectName = info.GetString("objectName");
}
}
/// <summary>
/// When serializing, sets the <see cref="T:System.Runtime.Serialization.SerializationInfo"/>
/// with information about the exception. </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds
/// the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="info"/> parameter is a null reference (Nothing in Visual Basic) </exception>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="*AllFiles*" PathDiscovery="*AllFiles*"/>
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter"/>
/// </PermissionSet>
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
base.GetObjectData(info, context);
// 'info' guaranteed to be non-null (base.GetObjectData() will throw an ArugmentNullException if it is)
info.AddValue("objectName", this.objectName);
}
/// <summary>
/// Gets or sets the name of the object not found </summary>
/// <value>The name of the object </value>
public string ObjectName {
get { return objectName; }
set { objectName = value; }
}
}
PS: Bevor mich jemand darauf anspricht: Der Grund für eine Basis Gs3Exception
die nicht mehr Wert hat als die ApplicationException
ist der Enterprise Library Exception Handling Application Block... indem wir eine Basisausnahme auf Anwendungsebene haben, können wir allgemeine Protokollierungsrichtlinien für Ausnahmen erstellen, die direkt von unserem Code ausgelöst werden.