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);