2011-01-04 21 views
16

私のコードは以下のようになります。例外の原因となったメソッドの名前を取得する方法

try 
{ 
    _productRepo.GetAllProductCategories(); 
} 
catch (Exception ex) 
{ 
    //Do Something 
} 

私は例外が私の結果としてGetAllProductCategories()メソッド、私は、このメソッド名を取得する必要があり、すなわち「GetAllProductCategories()」にスローされる場合は、上記の場合に想定、メソッド名を表示する方法が必要。どのように私にこのことを提案することができますか?

+1

簡単な答えは?コールスタックの一番上にあるメソッドです。これは、例外が発生する前に最近呼び出されたメソッドです。 :) – Chiramisu

+0

私はこの回答をチェックして解決しました。http://stackoverflow.com/questions/27997276/get-method-name-that-threw-exception –

答えて

1

stacktraceを見てください。

これは例外のプロパティです。

20

便利なはずのSystem.ExceptionTargetSiteというプロパティがあります。

現在の例外をスローするメソッドを取得します。あなたのケースでは

、あなたはおそらくのようなものとします。この 例外をスローするメソッドが使用できない場合

catch (Exception ex) 
{ 
    MethodBase site = ex.TargetSite; 
    string methodName = site == null ? null : site.Name; 
    ...   
} 

をそれが記載されている問題のいくつかを指摘する価値があります スタックトレースがNULL参照ではありません (Visual BasicではNothing)、TargetSite はスタックからメソッドを取得します トレース。スタックトレースがNULL 参照の場合、TargetSiteは ヌル参照を返します。

注:TargetSiteプロパティは 正確例外ハンドラ が アプリケーションドメインの境界を越えて例外を処理する場合、例外が がスローされた メソッドの名前を報告しないことがあります。

あなたは@leppieがあまりにも示唆するようStackTraceプロパティを使用することができますが、これは、スタックにあったフレームの文字列形式であることに注意してください。したがって、実行をスローしたメソッドのという名前のが必要な場合は、操作する必要があります。このメソッドは、ロギングハンドラクラスとメソッドGetType(の使用)のために書かれた

private string GetExecutingMethodName() 
{ 
    string result = "Unknown"; 
    StackTrace trace = new StackTrace(false); 
    Type type = this.GetType(); 

    for (int index = 0; index < trace.FrameCount; ++index) 
    { 
     StackFrame frame = trace.GetFrame(index); 
     MethodBase method = frame.GetMethod(); 

     if (method.DeclaringType != type && !type.IsAssignableFrom(method.DeclaringType)) 
     { 
      result = string.Concat(method.DeclaringType.FullName, ".", method.Name); 
      break; 
     } 
    } 

    return result; 
} 

3

それはたStackFrameにだが...単に実行最後として返されるのロギングハンドラクラス内のメソッドを排除します方法。ロギングハンドラクラスは単に例外を記録するだけではなく、新しいStackTraceオブジェクトが必要でした。明らかに、「例外を投げたメソッド」を見つけるために、GetType()は必要ないかもしれません。

スタックの一番上が必要な場合は、最初のフレームを取得し、GetMethod()を呼び出して返すか、単にTargetSiteを使用します。 GetType()を削除することができました。 StackTraceオブジェクトを作成するには、例外を渡す必要があることにも注意してください。例:

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      Test(); 
     } 
     catch (Exception ex) 
     { 

      // does not work properly - writes "Main" 
      Console.WriteLine(MethodBase.GetCurrentMethod()); 

      // properly writes "TestConsole.Program.Test" 
      Console.WriteLine(GetExecutingMethodName(ex)); 

      // properly writes "Test" 
      Console.WriteLine(ex.TargetSite.Name); 
     } 

     Console.ReadKey(); 
    } 


    static void Test() 
    { 
     throw new Exception("test"); 
    } 

    private static string GetExecutingMethodName(Exception exception) 
    { 
     var trace = new StackTrace(exception); 
     var frame = trace.GetFrame(0); 
     var method = frame.GetMethod(); 

     return string.Concat(method.DeclaringType.FullName, ".", method.Name); 
    } 
} 

基本的に、TargetSite()が必要な処理を行う場合、それ以上は実行しないでください。しかし、多くの場合、ロギングハンドラでは、例外オブジェクトは利用できません(つまり、トレースと監査)ので、最後に実行されたメソッドを取得するために新しいStackTrace()オブジェクトが必要になります。

+0

GetTypeとは何ですか?あなたが作成した別の方法ですか?組み込みのGetTypeは、参照するオブジェクトを必要とします。 – KingOfHypocrites

+0

@ KingOfHypocrites - GetType()は現在のクラスから呼び出されています。 –

+0

これは質問された質問にどのように当てはまるのかわかりません。このコードは、例外のスタックトレースとは無関係に、まったく新しい 'StackTrace'オブジェクトを生成します。また、.NETは、現在実行中のメソッドの 'MethodInfo'オブジェクトを取得するための完全に優れた(そしてより信頼できる)方法を既に持っています:[' MethodBase.GetCurrentMethod'](http://msdn.microsoft.com/en-us/ library/system.reflection.methodbase.getcurrentmethod(v = vs.110).aspx) –

関連する問題