Edw*_*win 14 c# reflection methods private
我正试图找到"打破非公开方法"的解决方案.
我只是想调用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);
}
Run Code Online (Sandbox Code Playgroud)
InternalGetCurrentMethod
声明在哪里:内部:-).
我使用反射调用方法没有问题,但这会弄乱调用堆栈,这只是必须要保留的一件事,否则它会破坏它的目的.
我的堆栈跟踪保持接近原始的几率是多少(至少在允许的StackCrawlMark
s 的距离内,这是LookForMe
,LookForMyCaller
和LookForMyCallersCaller
.是否有一些复杂的方法来实现我想要的?
Meh*_*dad 20
如果我喜欢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);
}
Run Code Online (Sandbox Code Playgroud)