5

I've a little problem with getting the caller for my extension method.

Searched the internet but couldn't find anything simular to my problem. This question was a close call...

I've a extension method :

public static void TabToNextField(this FrameworkElement i, FrameworkElement nextField)
{
   i.KeyPress(Keys.Tab);
   var isNextFieldFocused = nextField.GetProperty<bool>("IsFocused");

   if (!isNextFieldFocused)
   {
       //Taborder is incorrect. Next field wasn't focused!
       //This wont work since 'this' can't be used in a static context.
       var currentProcedure = this.GetType().Name;   
       var fromField = i.AutomationId;
       var toField = nextField.AutomationId;
       //Log to file..
   }
}

This is used for some automated tests to validate if the nextfield has focus and the tab order is correct. But for the error that should be logged i would like to get the Class name of the caller to get a accurate report that we can directly see where the error is in our application.

Since all the controls are using AutomationId the controls are easy to identify..

So the question is: How can i get the caller method from this extension method?

Community
  • 1
  • 1
Jonas W
  • 3,200
  • 1
  • 31
  • 44

2 Answers2

7

My solution was by using the CallerMemberName in .Net 4.5. So the final solution was as following :

public static void TabToNextField(this FrameworkElement i
    , FrameworkElement nextField
    , [CallerMemberName] string memberName = "")
{
    i.KeyPress(Keys.Tab);
    var isNextFieldFocused = nextField.GetProperty<bool>("IsFocused");

    if (!isNextFieldFocused)
    {
        //Taborder is incorrect. Next field wasn't active!
        var currentProcedure = memberName;
        var fromField = i.AutomationId;
        var toField = nextField.AutomationId;
    }
}

I hope this can help someone with simular issues.

Jonas W
  • 3,200
  • 1
  • 31
  • 44
6

While CallerMemberName is indeed handy, you can also use the StackTrace class, which is avaiable in all framework versions.


LINQPad Example:

void Main()
{
    "Test".Test();
}

static class Extensions
{
    public static void Test(this string s)
    {
        var method = new StackTrace().GetFrame(1).GetMethod();
        Console.WriteLine(String.Format("I was called from '{0}' of class '{1}'", method.Name, method.DeclaringType));
    }
}

Output:

I was called from 'Main' of class 'UserQuery'

sloth
  • 99,095
  • 21
  • 171
  • 219
  • +1, very nice. Didn't even think about the StackTrace.. I think that it's a better solution to my original problem then by using the CallerMemberName. Thanks for the input! – Jonas W Oct 02 '12 at 09:40
  • 2
    Getting a `StackTrace` is expensive, but on the plus side it gets you a whole `MethodInfo` rather than just the name. But other attributes can get you the source file and line number, which I don't think a `MethodInfo` can. – Rawling Oct 02 '12 at 09:43