例外に関する追加情報を提供する必要があるときはいつでも、実際にこれがrightの方法なのかと思います。
この質問のために、私は例を書きました。 Abbreviation
プロパティを更新したいクラスがあるとしましょう。 SOLIDの観点からは完全ではないかもしれませんが、worker-methodをいくつかのサービスでDIを介して渡しても、同じ状況が発生します-例外が発生しますそれにコンテキストはありません。例に戻ります...
class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }
}
次に、クラスのいくつかのインスタンスと、worker-methodが呼び出されるループがあります。 StringTooShortException
をスローできます。
var persons =
{
new Person { Id = 1, Name = "Fo" },
new Person { Id = 2, Name = "Barbaz" },
}
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
try
{
person.Abbreviation = GenerateAbbreviation(person.Name);
}
catch(Exception ex)
{
// ?
}
}
// throw AggregateException...
}
public IEnumerable<string> GenerateAbbreviation(string value)
{
if (value.Length < 5)
{
throw new StringTooShortException(value);
}
// generate abbreviation
}
問題は、Person
またはそのId
(またはその他)を追加する方法ですか?
私は次の3つのテクニックを知っています。
Data
プロパティを使用します長所:
try/catch
は不要短所:
Message
に簡単に統合することはできませんobject
です例:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
try
{
person.Abbreviation = GenerateAbbreviation(person.Name);
}
catch(Exception ex)
{
ex.Data["PersonId"] = person.Id;
// collect ex
}
}
// throw AggregateException...
}
長所:
Data
プロパティに似ていますが、強く型付けされていますMessage
への統合が容易短所:
例:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
try
{
person.Abbreviation = GenerateAbbreviation(person.Name);
}
catch(Exception ex)
{
// not suitable for this exception because
// it doesn't have anything in common with the Person
}
}
// throw AggregateException...
}
長所:
Message
は予測可能な方法でフォーマットできます短所:
try/catch
が必要例:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
try
{
try
{
person.Abbreviation = GenerateAbbreviation(person.Name);
}
catch(Exception ex)
{
throw new InvalidPersonDataException(person.Id, ex);
}
}
catch(Exception ex)
{
// collect ex
}
}
// throw AggregateException...
}
Data
[〜#〜] ftw [〜#〜] 。
あなたの「逆」:
->your例外タイプの場合、Message
をオーバーライドして、doesがData
.. Data
がメッセージ の場合にのみ、これを検討します。
例としてのNlogのグーグル yields :
例外レイアウトレンダラー
(...)
format-出力のフォーマット。例外プロパティのカンマ区切りリストである必要があります:
Message
、Type
、ShortType
、ToString
、Method
、StackTrace
&Data
。このパラメーター値では、大文字と小文字は区別されません。デフォルト:message
だからそれは簡単に設定できるようです。
えっ?そこにオブジェクトをダンプして、使用可能なToString()
メソッドがあることを確認してください。
また、キーに問題はありません。ちょっと穏やかな個性を使うだけでいいです。
免責事項:これは、質問からすぐにわかるものであり、Data
を15分間でググったものです。私はそれが穏やかに役立つと思ったので、私はそれを答えとして出しましたが、私はData
を自分自身で使用したことがないので、ここの質問者は私よりもこれについてもっと知っているかもしれません。
なぜ例外をスローするのですか?彼らを捕まえて取り扱ってもらうため。
例外を処理するために、キャッチコードはどのように機能しますかhow? Exceptionオブジェクトで定義したプロパティを使用します。
Messageプロパティを使用して例外を特定したり、潜在的なハンドラーが依存すべき「情報」を提供したりしないでください。それは単に揮発性が高すぎて信頼性が低い。
これまで「Data」プロパティを使用したことはありませんが、あまりにも一般的に聞こえます。
多くの例外のクラスを作成しない限り、それぞれが特定の例外的なケースを識別します-どのようにして知っていますか例外をキャッチしたとき何 "データ「を表す? (「メッセージ」に関する前のコメントを参照してください)。