MisterAcoustic
MisterAcoustic

Reputation: 105

How can I identify a specific call to a function automatically?

How can I identify a specific call to a function automatically?

This example is simplified, I have (somewhat) better reasons for wanting this than it would appear from the example.

If I have code that looks like this:

...
myObj.method1("locationA", otherParams);
...
myObj.method1("locationB", unrelatedParams);
...

I would like to know how I can automatically generate the identifiers to use in place of "locationA" and "locationB" so that I can tell which line of code is doing the calling.

It is not an option to hardcode an identifer for each location, and it cannot be, for example, a number that is incremented. It has to be the same identifier generated for the same function call each time.

My thoughts are that we might be able to use reflection (though I don't know if something like the IL line number is available), but I'm open to any other ideas about how to do this, as long as it meets the conditions above.

Thanks for your help.


More Info:

The inquirer is a colleague of mine and the answers provided seem to solve the issue, but in case there are better options I'll provide some additional information. The reason we want to identify a specific location is that we are prompting (sending a message back to the user to interact with) between server side code (c#) and client side code (JavaScript). If we have a series of prompts based on the state of the application, say, the first prompt happens if something is locked in the database and asks the user what to do (cancel, for example), and the second prompt occurs after. We need to process the first one before moving to the second, so we exit the server code passing back the first prompt.

When we code the prompt we dynamically assign an ID for it (in this case currently auto-incrementing an ID, to avoid hard-coding (i.e. 1, 2, 3, or guids, etc). This dynamic identification resets each time we call the method in question (so that the IDs are consistent; the first prompt has an id of "1", the second, "2").

The idea is that when the user answers and retries, we assign the answer(s) to a list and call the operation that then matches the prompt answer in the list with the specific prompt located in the code. Then we move on to the next prompt and then repeat the same process.

However, if by the time we come back into the method with the two prompts, and the lock no longer exists (first prompt), we don't branch to that section of the code (there's a check for locks before the prompt). Thus, we jump to the second prompt, but that second prompt would auto-generate an ID of 1, not 2 and think it already has an answer when it does not.

I've highlighted the code that creates the ID and sees if there is an answer that matches the prompt ID (the answer list is stored in PromptHandler):

enter image description here

Upvotes: 1

Views: 146

Answers (3)

inquisitive
inquisitive

Reputation: 3629

String callerName = (new StackTrace()).GetFrame(0).GetMethod().Name;

Int lineNo = (new StackTrace()).GetFrame(0).GetFileLineNumber();

Upvotes: 1

StriplingWarrior
StriplingWarrior

Reputation: 156469

.NET 4.5 has some tracing attributes that may suit your needs.

using System.Runtime.CompilerServices;

void Main()
{
    var myObj = new MyClass();
    myObj.Method1("foo", 1);
}

public class MyClass
{
    public void Method1(object someArgument, object someOtherArgument,
                 [CallerMemberName] string callerMemberName = null,
                 [CallerFilePath] string callerFilePath = null,
                 [CallerLineNumber] int callerLineNumber = 0)
    {
        Console.WriteLine(
             string.Format("Called with {0}, {1} from method {2} in file {3} at line number {4}",
                someArgument, someOtherArgument, 
                callerMemberName, callerFilePath, callerLineNumber));
    }
}

http://intellitect.com/new-attributes-for-tracelogging-information-in-net-4-5/

Upvotes: 1

Matt Houser
Matt Houser

Reputation: 36073

Using .NET 4.5, you can attribute your parameters with certain compiler "helpers" such as the calling line #, etc.

void method1(useful params, 
            [CallerFilePath] string filePath = "", 
            [CallerLineNumber] int lineNumber = 0) 
{ ... }

Then you would call allowing the compiler to supply the defaulted parameters:

myObj.method1(parameters);

Inside the function, those other parameters will be filled with useful information.

See the [CallerFilePath] attribute help for more information: http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callerfilepathattribute.aspx

Upvotes: 2

Related Questions