bukk530
bukk530

Reputation: 1895

Getting attributes of calling methods

I am working on a library where the entry points methods are labeled with some attribute. The internal methods need to know whether the original attribute on the entry point has a value of 1, 2, 3 ...

[MyAttribute(1)]
public void Method1() {
    InternalMethod();
}

[MyAttribute(2)]
public void Method2() {
    InternalMethod();
}

[MyAttribute(3)]
public void Method3() {
    InternalMethod();
}

The only way that I know to get the attribute is to traverse the stack up to the root and search for a method that has the MyAttribute attribute. The problem with this approach is that I am implementing it using the StackTrace class, which is too expensive as the methods are called during frequent HTTP requests that need to be as fast as possible.

Is there any way around this?

Upvotes: 1

Views: 1162

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1500175

Assuming that:

  • Your current stack traversal route works
  • You really don't want to do this explicitly as per TcKs's answer
  • You make calls from a relatively small number of places
  • Any particular direct call site to InternalMethod would only have one attribute in its stack trace (you don't have multiple calls from different places that then call InternalMethod() with different attribute values elsewhere in the stack)

If those assumptions are true, I have a pretty hacky suggestion...

Change the InternalMethod signature to

void InternalMethod([CallerFilePath] string file = null, [CallerLineNumber] int line = 0)

At that point, your InternalMethod() calls will get the path and line number arguments populated automatically by the compiler. That doesn't help you get the attribute - but it does mean you can perform the stack crawl for that call site once, and then populate a cache based on that file/line number combination. As a first pass, you could just cache based on $"{file}:{line}", but if you want even higher performance, you'd avoid the string concatenation via a more complicated cache.

Note that the compiler provides the file and line number, so it doesn't matter whether it's a release build, or if the method is inlined, etc.

Upvotes: 2

TcKs
TcKs

Reputation: 26632

Pass the number to the InternalMethod as argument.

Upvotes: 2

Related Questions