Получить метод вызова с помощью StackTrace - PullRequest
0 голосов
/ 24 июня 2018

У меня есть два сценария, в которых я хочу узнать, какой метод является вызывающим для какого-либо метода, который я выполняю.

Это сценарии:

1)

public static void ExecuteMethod(object obj)
{
    var mth = new StackTrace().GetFrame(1).GetMethod();
    string methodName = mth.Name;
}

И я называю это так:

public class Process
{
    public int Handle { get; set; }
    public string Name { get; set; }
    public int ProcessID { get; set; }

    public dynamic GetOwner()
    {
        return WMIMethod.ExecuteMethod(this);
    }
}

Когда это выполнено, результат methodName будет тем, который я ожидаю: GetOwner

Второй и проблемный сценарий такой:

2)

public static dynamic ExecuteMethod(object obj, dynamic parameters)
{
    var mth = new StackTrace().GetFrame(1).GetMethod();
    string methodName = mth.Name;
}

И я называю это так:

public class Process
{
    public int Handle { get; set; }
    public string Name { get; set; }
    public int ProcessID { get; set; }

    public dynamic GetOwner(dynamic inParams)
    {
        return WMIMethod.ExecuteMethod(this, inParams);
    }
}

В этом сценарии, когда я звоню new Process().GetOwner(new { MyParam = "Something" } ), результат methodName уже не тот, который я ожидал бы (GetOwner), и вместо этого methodName равен CallSite.Target, а результат mth это

{Void CallSite.Target(System.Runtime.CompilerServices.Closure, System.Runtime.CompilerServices.CallSite, System.Type, ORMi.Sample.Models.Printer, System.Object)}

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

Спасибо!.

1 Ответ

0 голосов
/ 24 июня 2018

Я обнаружил, что при использовании объекта dynamic C # добавляет дополнительный вызов метода System.Dynamic.UpdateDelegates.UpdateAndExecute3().

В вашем случае я бы переписал второй метод как

public static dynamic ExecuteMethod(object obj, dynamic p)
{
    var frame =
        new StackTrace().GetFrames()
                        .Skip(1) // Skip the 'ExecuteMethod'
                        .First(x => x.GetMethod().DeclaringType.Namespace != "System.Dynamic");

    return frame.GetMethod().Name;
}

К сожалению, я понятия не имею, почему C # вставляет этот вызов, поэтому я буду признателен, если кто-нибудь сможет объяснить эту внутреннюю работу.

...