C# Получение ClassName: Exception TargetSite.DeclaringType.Name Vs MethodBase.GetCurrentMethod (). DeclaryingType - PullRequest
0 голосов
/ 31 марта 2020

Я создаю простой метод логирования (ничего особенного) для операторов try / catch. Я хочу включить имя класса и метод, где было сгенерировано исключение.

Существует два разных способа получения информации. Один использует MethodBase.GetCurrentMethod() и исключение TargetSite.

Я знаю, что MethodBase может добавить проблему с производительностью, но будет совершенно незначительным для обычных операторов try / catch.

Я также понять, что оба могут иметь нулевые значения. Мой вопрос , какой процесс является предпочтительным, есть ли какие-либо недостатки или имеет ли это значение ?

Вот мой код, получающий оба

public static void LogError(Exception exp, MethodBase method) 
{
    var methodName = method.Name;
    var className = (method.ReflectedType != null) ? method.ReflectedType.Name : "";

    var methodName2 = exp.TargetSite!= null ? exp.TargetSite.Name : "";
    var className2 = (exp.TargetSite != null && exp.TargetSite.DeclaringType != null) ? exp.TargetSite.DeclaringType.Name : "";

    // do more stuff
}

Вот вызов метод

AuditDbContext.LogError(ex, MethodBase.GetCurrentMethod()); 

Если я использую TargetSite, я не передам в MethodBase (конечно).

ОБНОВЛЕНИЕ:

Включить информацию о вызывающем абоненте в качестве дополнительного возможного выбора. Спасибо Ллиар за комментарий.

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Если вы хотите записать имя класса и имя метода , где было сгенерировано исключение , то вам следует использовать Exception.TargetSite.

MethodBase.GetCurrentMethod() возвращает текущий метод. Этот метод может возвращать метод, отличный от метода, в котором было сгенерировано исключение.

Вот пример, показывающий разницу:

public static void Main()
{
    try
    {
        Demo();
    }
    catch (Exception e)
    {
        // Output: Program Demo
        Log1(e);

        // Output: Program Main
        Log2(e, MethodBase.GetCurrentMethod());
    }
}

public static void Demo()
{
    // Exception is thrown in Program.Demo
    throw new Exception();
}

public static void Log1(Exception exp) 
{
    var methodName = exp.TargetSite != null ? exp.TargetSite.Name : "";
    var className = (exp.TargetSite != null && exp.TargetSite.DeclaringType != null) ? exp.TargetSite.DeclaringType.Name : "";
    Console.WriteLine("{0} {1}", className, methodName);
}

public static void Log2(Exception exp, MethodBase method) 
{
    var methodName = method.Name;
    var className = (method.ReflectedType != null) ? method.ReflectedType.Name : "";
    Console.WriteLine("{0} {1}", className, methodName);
}
0 голосов
/ 31 марта 2020

Лучший способ для меня - создать Stacktrace и получить оттуда имя метода. Это метод, который я использую для этого:
Просто дайте мне знать, если вы хотите увидеть весь класс, который я использую для ведения журнала


private static void MessageInfoForLog(out string methodName, out string className, int frameDepth)
    {
        StackTrace stackTrace = new StackTrace();
        var frame = stackTrace.GetFrame(frameDepth + 2); //+2 only if you go from your method to Log and log access this method here --> Exception --> Log (1) --> MessageInfoForLog(2)
        var method = frame.GetMethod();

        className = method.ReflectedType.Name;
        methodName = method.Name;
    }

...