只有累積,沒有奇蹟

2019年1月26日 星期六

[.NET] 使用 MethodBase.GetCurrentMethod 取得執行方法資訊

前言 
在過去 method 發生例外用 catch 包起來時,往往 catch 寫的 logName 都是 hard Code 寫死 method Name,但常常會發生 copy 來 copy 去的時候忘記改寫死的 method name 造成 log 寫錯誤狀況發生,之前使用 C# 4.5 提供的 CallerMemberName attribute 解決此問題簡單範例如下
private void Test(string message, [CallerMemberName] string memberName = "")
{
    try
    {
        // do something
    }
    catch (Exception e)
    {
        Console.WriteLine($"Error Method : {memberName} , Message : {message}");
    }
}
但在 Method 都必須加上參數 CallerMember,此篇文章介紹另一種方式解決此問題

使用方式
在命名空間 System.Reflection 可以用 MethodBase 靜態方法取得當前方法的相關資訊,使用方式如下所示
MethodBase.GetCurrentMethod()
在 GetCurrencyMethod 方法還可以取得方法名稱、命名空間、全名等資訊
MethodBase.GetCurrentMethod().Name ;
MethodBase.GetCurrentMethod().DeclaringType.Namespace;
MethodBase.GetCurrentMethod().DeclaringType.FullName;
再回到今天想解決的問題,在發生例外使用用 Methodbase 取代 CallerMember 取得當下執行的方法,即可不用在 hardCode 在例外的訊息中,不用擔心 copy 到其他地方要再修改的問題,使用前須先using system.reflection 命名空間範例 Code 如下
using System.Reflection;

static void Main(string[] args)
{
    // 目前執行方法的類別名稱
    Console.WriteLine($"GetCurrentMethod.Name : {MethodBase.GetCurrentMethod().Name}");
    // 目前執行方法的命名空間
    Console.WriteLine($"GetCurrentMethod.DeclaringType.Namespace : {MethodBase.GetCurrentMethod().DeclaringType.Namespace}");
    // 目前執行方法的全名
    Console.WriteLine($"GetCurrentMethod.DeclaringType.FullName : {MethodBase.GetCurrentMethod().DeclaringType.FullName}");

    try
    {
        CallForException();
    }
    catch (Exception e)
    {
        Console.WriteLine("Exception Method Name : {0} ", GetException(MethodBase.GetCurrentMethod(), e));
    }

    Console.ReadKey();
}

private static string GetException(MethodBase methodBase, Exception e)
{
    StackTrace trace = new StackTrace(e);
    StackFrame previousFrame = null;

    foreach (StackFrame frame in trace.GetFrames())
    {
        if (frame.GetMethod() == methodBase)
        {
            break;
        }

        previousFrame = frame;
    }

    return previousFrame?.GetMethod().Name;
}

private static void CallForException()
{
    DoActualException();
}

private static void DoActualException()
{
    throw new NotImplementedException();
}
輸出
上面 sample Code 輸出如下
  • 執行的 method Name 為 main
  • 執行的 method Name 命名空間為 consoleApp1 
  • 發生例外 try catch 裡的方法名稱為 CallForException
輕鬆上手,打完收工 !!

參考
MethodBase.GetCurrentMethod Method

0 意見:

張貼留言

Copyright © m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com