2

Consider the following code:

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

How can I find name of the executing function and object type? Any other solution except using [CallerFilePath] and [CallerMemberName]?

user2341923
  • 4,537
  • 6
  • 30
  • 44
  • Tell us your target .NET version. – Hamlet Hakobyan Mar 26 '14 at 12:29
  • [You may want to refer answer on this page][1] [1]: http://stackoverflow.com/questions/3456994/how-to-use-net-reflection-to-determine-method-return-type-including-void-and – Gaurav K. Mar 26 '14 at 12:30
  • possible duplicate of [How can I find the method that called the current method?](http://stackoverflow.com/questions/171970/how-can-i-find-the-method-that-called-the-current-method) – Dmitry Mar 26 '14 at 12:30
  • Anyone who wants [CallerTypeName] to exist please vote on https://github.com/dotnet/csharplang/issues/87 – Chris Marisic Jun 07 '17 at 21:47

5 Answers5

3
 string thisFunction = Reflection.MethodBase.GetCurrentMethod().Name; 
 string thisType = this.GetType().Name;
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • Doesn't this return the name of the current -, namly the `PrintLog` method? – MrPaulch Mar 26 '14 at 12:41
  • No, it will return the name of the currently executing method. – Selman Genç Mar 26 '14 at 12:44
  • Exacatly! The OP want's to put this code into the `PrintLog` method, which would be *currently executing* at the time of this query. So you won't get the caller will you? – MrPaulch Mar 26 '14 at 12:45
  • @MrPaulch where did you see OP wants to put this into `PrintLog` ? I can't see it? the `function` and `type` are just parameters.he wants to get the name of the method and type then pass them to `PrintLog` method (in the **Foo**) – Selman Genç Mar 26 '14 at 12:46
  • Sorry you are right. He didn't. I am just thinking, this portion *belongs* into the `PrintLog` method – MrPaulch Mar 26 '14 at 12:48
2

Int .Net4.5 you have the CallerMemberNameAttribute

Allows you to obtain the method or property name of the caller to the method.

Also you may try with:

new StackFrame(1).GetMethod().Name;

Also check this interesting link answer:- Can you use reflection to find the name of the currently executing method?

Community
  • 1
  • 1
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
1

If you can live with the path rather than the type name:

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

For instance methods you might choose to use GetType() to obtain the current type - this is not possible for static methods, though. So you could use:

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

with:

Log.PrintLog(this);
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • @HamletHakobyan actually, not quite - it is a **compiler** feature, not a runtime feature. If you are using the later C# compiler, you can use this feature on older frameworks simply by declaring the attribute yourself in the correct namespace. – Marc Gravell Mar 26 '14 at 12:38
  • I.e syntactical sugar? Didn't know. Thanks. But, from other site, again IMO, the compiler is part of framework, then we can said since .net 4.5 :) – Hamlet Hakobyan Mar 26 '14 at 12:40
  • That was my original solution, but [CallerFilePath] does not show type name in a nice way. – user2341923 Mar 26 '14 at 12:42
  • @XyiTebe do you see what I'm doing in the second example with `obj` ? But yes, it is a shame that there is no `[CallerTypeName]` – Marc Gravell Mar 26 '14 at 12:43
  • What if the class is static? – user2341923 Mar 26 '14 at 12:51
  • @XyiTebe I discussed that in the answer; you would just have to settle for the filename, assuming you don't want to use `typeof(...)` – Marc Gravell Mar 26 '14 at 13:09
  • @MarcGravell and anyone else interested in [CallerTypeName] please vote on https://github.com/dotnet/csharplang/issues/87 – Chris Marisic Jun 07 '17 at 21:47
1

Generally you can create a StackTrace anywhere you want:

StackTrace st = new StackTrace();

Then it's just about cycling through the StackFrames:

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

You could even identify the class and parameters (you have the MethodInfo object to play around with)

Personally I put the Time TID caller class+type+name into my logging context.


As I understand you wanted to parse the function name and type to the PrintLog function. Thats just messy!

The beauty of this approach is, that you don't have to do that. You can retreive the name and type of the caller within the PrintLog method.

MrPaulch
  • 1,423
  • 17
  • 21
0

As explained here you may use MethodInfoclass to find return type as MethodInfo.ReturnType

Community
  • 1
  • 1
Gaurav K.
  • 67
  • 2
  • 3
  • 10