c# - 调用私有(private)方法保留调用栈

标签 c# reflection methods private

我正在尝试找到“闯入非公共(public)方法”的解决方案。

我只想调用RuntimeMethodInfo.InternalGetCurrentMethod(...),传递我自己的参数(这样我就可以实现GetCallingMethod()),或者直接使用RuntimeMethodInfo.InternatGetCurrentMethod(ref StackCrawlMark.LookForMyCaller) 在我的日志例程中。 GetCurrentMethod 实现为:

[MethodImpl(MethodImplOptions.NoInlining)] 
public static MethodBase GetCurrentMethod() 
{     
    StackCrawlMark lookForMyCaller = StackCrawlMark.LookForMyCaller;     
    return RuntimeMethodInfo.InternalGetCurrentMethod(ref lookForMyCaller); 
}

声明 InternalGetCurrentMethod 的地方:内部 :-)。

使用反射调用方法没有问题,但这会弄乱调用堆栈,而这只是必须保留的一件事,否则就达不到目的了。

我保持堆栈跟踪接近原始的几率有多大(至少在允许的 StackCrawlMark 的距离内,它们是 LookForMeLookForMyCallerLookForMyCallersCaller。是否有一些复杂的方法可以实现我想要的?

最佳答案

如果我喜欢 C# 的一件事,那就是动态方法。

它们让您绕过 .NET 创建者的每一个目标和意图。 :D

这是一个(线程安全的)解决方案:

(Eric Lippert,请不要读这个...)

enum MyStackCrawlMark { LookForMe, LookForMyCaller, LookForMyCallersCaller, LookForThread }
delegate MethodBase MyGetCurrentMethodDelegate(ref MyStackCrawlMark mark);
static MyGetCurrentMethodDelegate dynamicMethod = null;

static MethodBase MyGetCurrentMethod(ref MyStackCrawlMark mark)
{
    if (dynamicMethod == null)
    {
        var m = new DynamicMethod("GetCurrentMethod",
            typeof(MethodBase),
            new Type[] { typeof(MyStackCrawlMark).MakeByRefType() },
            true //Ignore all privilege checks :D
        );
        var gen = m.GetILGenerator();
        gen.Emit(OpCodes.Ldarg_0); //NO type checking here!
        gen.Emit(OpCodes.Call,
            Type.GetType("System.Reflection.RuntimeMethodInfo", true)
                .GetMethod("InternalGetCurrentMethod",
                    BindingFlags.Static | BindingFlags.NonPublic));
        gen.Emit(OpCodes.Ret);
        Interlocked.CompareExchange(ref dynamicMethod,
            (MyGetCurrentMethodDelegate)m.CreateDelegate(
                typeof(MyGetCurrentMethodDelegate)), null);
    }
    return dynamicMethod(ref mark);
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Test()
{
    var mark = MyStackCrawlMark.LookForMe; //"Me" is Test's _caller_, NOT Test
    var method = MyGetCurrentMethod(ref mark);
    Console.WriteLine(method.Name);
}

关于c# - 调用私有(private)方法保留调用栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5143068/

相关文章:

c# - 在使用 Entity Framework 的分层架构中,我应该从 BLL 返回 POCO 类吗? (需要架构指导)

c# - EntityCommandCompilationException 指定的方法不支持 Entity Framework

c# - DataGrid 自动生成的列 : Increasing width

java - 关于 java : get `String[].class` from `String.class` , 如果 `String.class` 是 "runtime type"怎么办?

pointers - 如何从接口(interface){}获取结构成员的指针

python - 为 DataFrames 创建我自己的方法(python)

Ruby 操作符方法调用与普通方法调用

c# - 将类的实例作为参数传递给属性构造函数

java - 试图理解Java中两个多态命令之间的区别

java - 字段子类访问 - 最好的方法