Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#无堆栈跟踪的Get调用方法_C#_.net - Fatal编程技术网

c#无堆栈跟踪的Get调用方法

c#无堆栈跟踪的Get调用方法,c#,.net,C#,.net,我注意到.NET 4.5有一个名为[CallerMemberNameAttribute]的新属性,当附加到方法的参数时,该属性将提供调用该方法的方法的字符串名称(如果有意义的话) 然而,不幸的是(因为我想用XNA制作一些东西),我只针对.NET4.0 我希望能够做到以下几点: void MethodA() { MethodB(); } void MethodB() { string callingMethodName = (...?); Console.WriteLine(c

我注意到.NET 4.5有一个名为[CallerMemberNameAttribute]的新属性,当附加到方法的参数时,该属性将提供调用该方法的方法的字符串名称(如果有意义的话)

然而,不幸的是(因为我想用XNA制作一些东西),我只针对.NET4.0

我希望能够做到以下几点:

void MethodA() {
   MethodB();
}

void MethodB() {
   string callingMethodName = (...?);
   Console.WriteLine(callingMethodName);
}
我的输出将是MethodA

我知道我可以通过堆栈跟踪做到这一点,但这是a)不可靠的,b)缓慢的。。。 所以我想知道是否有任何其他的方法来收集这些信息,然而这可能是


我希望任何人在这个问题上都能有任何想法或知识。提前感谢:)

如果您使用Visual Studio 2012编译此文件,您可以编写自己的
CallerMemberNameAttribute
,并以与.NET 4.5相同的方式使用它,即使您仍然以.NET 4.0或3.5为目标。编译器仍将在编译时执行替换,即使是针对较旧的框架版本

只需将以下内容添加到项目中即可:

namespace System.Runtime.CompilerServices
{
    public sealed class CallerMemberNameAttribute : Attribute { }
}

您可以将调用方名称作为参数提供给被调用的方法。不完全符合您的要求,但它可以在无需访问堆栈帧的情况下工作:

[MethodImpl(MethodImplOptions.NoInlining)]
void MethodA() 
{
    string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
    MethodB(methodName);
}

void MethodB(string callingMethodName) 
{
    Console.WriteLine(callingMethodName);
}
通过使用
MethodBase.GetCurrentMethod()
,您可以确保实现仍然是重构安全的–如果方法的名称发生更改,结果仍然是正确的


别忘了用
MethodImplOptions.noinline
标记调用方法,以避免方法内联。

将调用方法名称作为字符串传递?@Oded很好是的,很明显我可以调用MethodB(“MethodA”),但重点是我正在尝试动态地进行,因此,如果我将MethodA更改为MethodC,我也不必编辑该调用。您在问题中没有指出这一点。“我可以在.NET4.0中使用.NET4.5功能吗?”不太可能。不容易。堆栈跟踪可能是在.NET 4.0中实现这一点的最佳动态方式。显然,您可以使用与ExtensionAttribute相同的技巧。如果这是一个愚蠢的问题,我只是一个业余程序员,非常抱歉,但是有没有办法查看Microsoft的CallerMemberNameAttribute的源代码?一般来说,你可以使用ILSpy反编译.NET库。然而,属性很少产生任何有趣的东西,因为有趣的部分更多的是其他代码如何使用它。例如,根据@ReedCopsey的说法,转换是由编译器在编译时完成的,而不是由属性本身完成的,而且您甚至不需要.NET 4.5运行时,因此您可能看不到有趣的代码。啊,那么编译器只看到名称“CallerMemberNameAttribute”并插入自己的逻辑?如果是这样的话,我可以用这个名字创建一个空白属性,它会工作吗?哦,我的天啊,神奇!你是个巫师吗?我想更多地了解编译器替换的魔力,即使是针对较旧的框架,正确的术语是什么?@user1249190我不知道这篇文章在哪里发表过——这只是我尝试过的东西,而且很有效;)由于它是一个编译器特性,一般来说,编译器并不关心您使用的是哪个框架,而是寻找模式来实现特性。