C# 如何找到执行函数的对象类型和名称?
考虑以下代码:C# 如何找到执行函数的对象类型和名称?,c#,.net,logging,reflection,clr,C#,.net,Logging,Reflection,Clr,考虑以下代码: class A { public void Foo() { string thisFunction = // get the name of the executing function (Foo) string thisType = // get the name of the object type (A) Log.PrintLog(thisFunction, thisType); } } public
class A
{
public void Foo()
{
string thisFunction = // get the name of the executing function (Foo)
string thisType = // get the name of the object type (A)
Log.PrintLog(thisFunction, thisType);
}
}
public static class Log
{
public static void PrintLog(string function, string type)
{
Console.WriteLine("Call from function {0}, type {1}", function, type);
}
}
如何找到执行函数的名称和对象类型?
除了使用[CallerFilePath]和[CallerMemberName]之外的任何其他解决方案?Int.Net4.5您拥有
允许您获取调用程序的方法或属性名
方法
您也可以尝试以下方法:
new StackFrame(1).GetMethod().Name;
另请查看此有趣的链接答案:-如前所述,您可以使用
MethodInfo
类查找返回类型作为MethodInfo.ReturnType
,如果您可以使用路径而不是类型名称:
class A
{
public void Foo()
{
Log.PrintLog();
}
}
public static class Log
{
public static void PrintLog([CallerMemberName] string function = null,
[CallerFilePath] string path = null)
{
Console.WriteLine("Call from function {0}, file {1}", function, path);
}
}
例如,您可以选择使用GetType()
来获取当前类型的方法-但是,这对于静态方法是不可能的。因此,您可以使用:
public static void PrintLog(object obj = null,
[CallerMemberName] string function = null,
[CallerFilePath] string path = null)
{
string name = obj == null ? path : obj.GetType().Name;
Console.WriteLine("Call from function {0}, name {1}", function, name);
}
与:
通常,您可以在任意位置创建StackTrace:
StackTrace st = new StackTrace();
然后就是在堆叠框架中循环:
StackFrame[] sf = st.GetFrames();
// in case your PrintLog has overloads or recursions
// it may appear several times in the stack
string ownName = "PrintLog";
MethodInfo curMethod = null;
for(int i = 0; i < sf.Length; i++) {
curMethod = sf[i].GetMethod();
if(ownName != curMethod.Name)
break;
}
Console.WriteLine("Call from function {0}, type {1}",
curMethod.Name,
curMethod.DeclaringType.Name);
StackFrame[]sf=st.GetFrames();
//如果您的打印日志有重载或递归
//它可能在堆栈中出现多次
字符串ownName=“PrintLog”;
MethodInfo curMethod=null;
对于(int i=0;i
您甚至可以识别类和参数(您可以使用MethodInfo对象)
就我个人而言,我将Time TID caller类+类型+名称放入日志上下文中
据我所知,您希望将函数名和类型解析为
PrintLog
函数。那太乱了
这种方法的美妙之处在于,你不必这么做。您可以在
PrintLog
方法中检索调用方的名称和类型。告诉我们您的目标.NET版本。[您可能需要参考此页上的答案][1][1]:任何希望[CallerTypeName]存在的人的可能重复请通过StackFrame
对解决方案进行投票未经验证,因为编译器可以优化(内联)某些方法。@HamletHakobyan实际上,不完全是-它是一个编译器功能,而不是运行时功能。如果您使用的是更高版本的C#编译器,那么只需在正确的名称空间中声明属性,就可以在较旧的框架上使用此功能?我不知道。谢谢但是,在另一个站点,同样在我看来,编译器是框架的一部分,那么我们可以说,因为.net 4.5:)这是我最初的解决方案,但是[CallerFilePath]并没有以一种很好的方式显示类型名。@XyiTebe您看到我在第二个示例中使用obj
所做的事情了吗?但是是的,遗憾的是没有[CallerTypeName]
如果类是静态的怎么办?这不返回当前的名称吗?只返回PrintLog
方法吗?不,它将返回当前执行的方法的名称。例如!OP希望将此代码放入PrintLog
方法中,该方法在执行此查询时当前正在执行。那么你就不会接到来电了,是吗?@Paulch先生你在哪里看到OP想把这个放到PrintLog
?我看不见?函数
和类型
只是参数。他想得到方法的名称并键入,然后将它们传递给PrintLog
方法(在Foo中)。对不起,你是对的。他没有。我只是在想,这部分属于PrintLog
方法通过StackFrame
的解决方案没有得到验证,因为编译器可以优化(内联)一些方法。那么您的建议是什么?
StackTrace st = new StackTrace();
StackFrame[] sf = st.GetFrames();
// in case your PrintLog has overloads or recursions
// it may appear several times in the stack
string ownName = "PrintLog";
MethodInfo curMethod = null;
for(int i = 0; i < sf.Length; i++) {
curMethod = sf[i].GetMethod();
if(ownName != curMethod.Name)
break;
}
Console.WriteLine("Call from function {0}, type {1}",
curMethod.Name,
curMethod.DeclaringType.Name);