2009-07-08 4 views
5

カスタム例外を扱う、私は通常、Exceptionから継承され、その後、いくつかの追加情報格納するために私の例外クラスにいくつかのフィールド/プロパティを追加する場合:上記の例ではカスタム例外内にデータを保存するにはどうすればよいですか?

public class MyException : Exception 
{ 
    public int ErrorCode{get;set;} 

    public MyException() 
    {} 
} 

を、ErrorCode値は例外に保存されていますつまり、保護されたコンストラクタのSerializationInfoオブジェクトとオーバーライドされたGetObjectDataメソッドの場合は、それを追加してリタイアする必要があります。

例外に関する追加のユーザー定義情報を提供するキー/値ペアのコレクションを取得します:

Exceptionクラスは、MSDNに記載Data性質を有しています。

私はData内部エラーコードを格納した場合、それは私の例外クラスは、今のように見えることを意味し、(リフレクターに応じて)例外クラスによって私のためにシリアライズされます:

public class MyException : Exception 
{ 
    public int ErrorCode 
    { 
     get {return (int) Data["ErrorCode"];} 
     set {Data["ErrorCode"] = value;} 
    } 

    public MyException() 
    {} 
} 

この手段をエラーコードの取得/設定(キャストエラーやエラーコードが辞書にないかもしれない状況など)に対処するにはもう少し作業が必要ですが、シリアル化について心配する必要はありません/それをデシリアライズする。

同じことを達成するには2つの方法がありますか、もう1つの方法で明確な利点がありますか?

答えて

1

私はあなたのコントロール下にないので、データを使用しないでください。どこかのコードが "ErrorCode"値を上書きすることを決定するかもしれません。代わりに、そのプロパティを使用してシリアル化を実装します。以下のコードを使用して、すべてのカスタム例外をテストして、それらを正しく実装していることを確認します。

public static void TestCustomException<T>() where T : Exception 
{ 
    var t = typeof(T); 

    //Custom exceptions should have the following 3 constructors 
    var e1 = (T)Activator.CreateInstance(t, null); 

    const string message = "message"; 
    var e2 = (T)Activator.CreateInstance(t, message); 
    Assert.AreEqual(message, e2.Message); 

    var innerEx = new Exception("inner Exception"); 
    var e3 = (T)Activator.CreateInstance(t, message, innerEx); 
    Assert.AreEqual(message, e3.Message); 
    Assert.AreEqual(innerEx, e3.InnerException); 

    //They should also be serializable 
    var stream = new MemoryStream(); 
    var formatter = new BinaryFormatter(); 
    formatter.Serialize(stream, e3); 
    stream.Flush(); 
    stream.Position = 0; 
    var e4 = (T)formatter.Deserialize(stream); 
    Assert.AreEqual(message, e4.Message); 
    Assert.AreEqual(innerEx.ToString(), e4.InnerException.ToString()); 
} 
0

最初の解決策を検討する必要があります。添付ファイル付きの行Exceptionインスタンスを作成する予定がない限り、Dataプロパティでは大した価値はありません。

独自の例外タイプがある場合は、代わりにプロパティを使用します。よりクリーンで安全です。

1

Microsoft's own guidelines

は例外がシリアライズ可能ですか。例外は、アプリケーションドメインとリモート境界で正しく動作するためには、直列化可能でなければなりません。

私は悲しいことに、外部のコードが同意なしに値を変更したり、解決策1(あなたの例では)を使用するが、シリアル化できるようにするデータプロパティに格納します。最終的に私はおそらく解決策1に行くので、値が決して変化しないことを確かめることができます。

5

独自の例外を作成する場合は、Dataプロパティは必要ありません。データは、既存の例外クラスに少しの余分な情報を格納したいが、独自のカスタム例外クラスを作成したくない場合に便利です。

関連する問題