27

いくつかの追加フィールドを含むカスタム例外クラスがあります。これらをメソッドに書き出すようにしたいのですToString()が、独自に実装すると、ToString()他の便利なもの(例外タイプ名、内部例外データ、スタックトレースの記述など)が失われます。

ToString()そのような例外に対して独自のメソッドを実装するための最良の方法/パターンは何ですか?理想的には、既存のメカニズムを再利用する必要がありますが、デフォルトのToString()実装と同様の方法でフォーマットされます。

更新:カスタムフィールドをbase.ToString()テキストに追加または追加することは、理想的なIMHOではありません。

PimTool.Utilities.OERestServiceUnavailableException: test ---> System.InvalidOperationException: inner message
   --- End of inner exception stack trace ---
   at PimTool.Tests.Services.OE.OERestClientTests.ExceptionsLogging() in D:\svn\NewPimTool\PimTool.Tests\Services\OE\OERestClientTests.cs:line 178, 
   StatusCode=0, message='test', requestId='535345'

カスタムフィールドが(潜在的に長い)例外の説明の最後に書き込まれることを意味します。一方、例外タイプは、説明に最初に記述される情報にする必要があります。

更新2:私はこれに対する解決策を実装しました。以下で私自身の答えを探してください。

4

7 に答える 7

38

これはすべてやり過ぎです。例外は、メッセージプロパティをオーバーライドするだけです。

public override String Message {
    get {  
        return base.Message + String.Format(", HttpStatusCode={0}, RequestId='{1}'", 
                    httpStatusCode, 
                    RequestId);
    }
}

ExceptionクラスのデフォルトのToStringメソッドは、基本的に「ClassName: Message --> InnerException.ToString() StackTrace」です。したがって、メッセージをオーバーライドすると、メッセージテキストが本来あるべき場所に正確に配置されます。

于 2014-11-07T14:02:03.653 に答える
14

ToString例外プロパティを確認することで、によって返される文字列にデフォルトデータを手動で追加できます。たとえば、以下は、例外のToStringメソッドによってデフォルトで返されるデータをシミュレートします(内部例外がないと仮定します)。

string.Format("{0}: {1}\r\n{2}", this.GetType().Name, this.Message, this.StackTrace);

base.ToStringまたは、追加したい情報に返されるデータを単純に追加(または追加)することもできます。

于 2009-12-11T08:28:53.387 に答える
12

OK、これが私が思いついたものです。例外をフォーマットするための元のメカニズムを複製する拡張クラスを実装しましたが、ひねりを加えました。カスタムフィールドをフォーマットするためのプラグインを提供するカスタムアクションデリゲート:

public static class ExceptionFormatterExtensions
{
    public static string ExceptionToString (
        this Exception ex, 
        Action<StringBuilder> customFieldsFormatterAction)
    {
        StringBuilder description = new StringBuilder();
        description.AppendFormat("{0}: {1}", ex.GetType().Name, ex.Message);

        if (customFieldsFormatterAction != null)
            customFieldsFormatterAction(description);

        if (ex.InnerException != null)
        {
            description.AppendFormat(" ---> {0}", ex.InnerException);
            description.AppendFormat(
                "{0}   --- End of inner exception stack trace ---{0}",
                Environment.NewLine);
        }

        description.Append(ex.StackTrace);

        return description.ToString();
    }
}

これで、フォーマットコードを複製することなく、独自のToString()実装でこのメソッドを使用できます。

    public override string ToString()
    {
        return this.ExceptionToString(
            description =>
            {
                description.AppendFormat(
                    ", HttpStatusCode={0}, RequestId='{1}'", 
                    httpStatusCode, 
                    RequestId);
            });
    }
于 2009-12-11T09:23:43.187 に答える
10

ToString()メソッドをオーバーライドして独自のカスタム情報を含めても、次のようにデフォルトの基本例外ToString()を呼び出すことができます。

public class MyException : Exception
{
    public string CustomField { get; set; }
    public override string ToString()
    {
        return CustomField + Environment.NewLine + base.ToString();
    }
}
于 2009-12-11T08:31:06.143 に答える
4

主にデバッガーでそれらを表示している場合は、属性を使用してそれらのフォーマットを指定でき、既存のメソッド[DebuggerDisplay]には触れません。ToString

それ以外の場合は、オーバーロードToStringして、必ず基本クラスバージョンを呼び出してくださいbase.ToString()

于 2009-12-11T08:32:12.630 に答える
1

オーバーライド呼び出しbase.ToString()内で、必要に応じて結果の文字列を変更します。

于 2009-12-11T08:29:26.943 に答える
1

最も簡単な方法

public override string ToString()
{
    StringBuilder sb = new();
    var separator = new string[] { Environment.NewLine };
    var str = base.ToString().Split(separator, 2, StringSplitOptions.None);
    sb.AppendLine(str[0]);

    // Your properties

    sb.Append(str[1]);
    return sb.ToString();
}
于 2021-03-21T09:24:02.670 に答える