C# 使用StackTrace获取调用方法
我有两个场景,我想知道哪个是我正在执行的某个方法的调用方方法 以下是场景: (一) 我这样称呼它:C# 使用StackTrace获取调用方法,c#,reflection,system.reflection,C#,Reflection,System.reflection,我有两个场景,我想知道哪个是我正在执行的某个方法的调用方方法 以下是场景: (一) 我这样称呼它: public class Process { public int Handle { get; set; } public string Name { get; set; } public int ProcessID { get; set; } public dynamic GetOwner() { return WMIMethod.Exe
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);
}
}
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);
}
}
执行此操作时,methodName
的结果就是我期望的结果:GetOwner
第二种也是有问题的情况是:
(二)
我这样称呼它:
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);
}
}
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);
}
}
在这个场景中,当我调用newprocess().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)}
谁知道为什么第二个案例与第一个不同??。如何解决这个问题
谢谢 我发现,当使用
dynamic
对象时,C#会添加一个额外的方法调用System.dynamic.updateLegates.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#会插入那个调用,所以如果有人能解释一下内部工作,我将不胜感激。你看过吗?@dman2306我试图避免使用,因为它迫使我向该方法添加另一个参数。。。我正在努力建立一个易于使用的图书馆。。。此属性的用法即使有效。。。我从StackTraceis获得的重定值不如我得到的重定值干净。是否可能有一个函数正在内联,因此不在堆栈上?@NicoRiff您可以为CallerMemberName参数指定一个默认值,以便调用方或方法用户可以忽略它,因为编译器将对其进行设置。大量使用
动态
。DLR必须“加速”。这有点像编译器在运行时再次运行。它在第一次缓存每个调用站点的信息,因此不必在每次调用代码时都重新编译。我认为所有这些“巫术”都是通过实际编译器插入到代码中的额外方法调用/委托调用来完成的。我相信如果你反编译代码,它们会很明显(我承认我从来没有检查过)谢谢@Kyrylo它工作得很好,但我不得不做一些调整,只跳过2而不是1。它是这样工作的:var frame=newstacktrace().GetFrames().Skip(2).First(x=>x.GetMethod().DeclaringType.Namespace!=“System.Dynamic”)@nicorif如果总是将此
传递给该方法,还可以使用x.GetMethod().DeclaringType
利用其类型和过滤器。