tags:

views:

827

answers:

4

What I'm wondering is if it's possible to (for instance) to walk up the stack frames, checking each calling object to see if matches an interface, and if so extract some data from it.

Yes, I know it's bad practice, I'm wondering if it's possible.

A: 

See this question:
http://stackoverflow.com/questions/44153/can-you-use-reflection-to-find-the-name-of-the-currently-executing-method

It's not a duplicate, but the answer to that question will answer yours as well.

Joel Coehoorn
Not really - because while it's feasible to get the calling method, that doesn't tell you the actual type of the object making the call. For instance, it could be in BaseClass.Foo() but from an instance of DerivedClass which implements an interface that Andrew is looking for.
Jon Skeet
It does give you a stack trace, though.
Joel Coehoorn
Yes, but the way I read the question that isn't enough.
Jon Skeet
+5  A: 

No, there isn't - at least not without using a profiling/debugging API of some description. You can walk the stack to find the calling method, with the caveat that it's really slow and may be inaccurate due to JIT optimisations. That won't tell you what the calling object is though (if indeed there is one).

Jon Skeet
Aaaah - so presumably VS does it in some kind of complicated way by instrumenting the code?
Andrew Ducker
Well, not by instrumenting the code so much as running the debugger APIs which give all kinds of information - at a price, of course.
Jon Skeet
Oooh - where can I find moer info on these debugger APIs?
Andrew Ducker
andrewducker: To be honest, I'd just be doing Google searches to find out, so I'll let you do those instead :) I've never used the debugger/profiler APIs - given the low-level stuff they're for, I expect they may be a pain to use.
Jon Skeet
So this nailed me with some logging code that was trying to be too clever, examining the StackTrace and going up frames to get the name of the calling method. You can do that by simple counting in Debug mode, but in Release mode, well, some methods get optimized away. A great tip!
Nicholas Piasecki
A: 

If you want to get the type you can try this:

new StackFrame(1).GetMethod().DeclaringType

As Jon pointed out there might be issues if you run into jit optimisizations.

As for getting data from the object, I don't think it's possible.

Edit

Just to elaborate on the optimization issue, take the following code:

class stackTest
    {
        public void Test()
        {
            StackFrame sFrame = new StackFrame(1);
            if (sFrame == null)
            {
                Console.WriteLine("sFrame is null");
                return;
            }

            var method = sFrame.GetMethod();

            if (method == null)
            {
                Console.WriteLine("method is null");
                return;
            }
            Type declaringType = method.DeclaringType;
            Console.WriteLine(declaringType.Name);
        }

        public void Test2()
        {
            Console.WriteLine(new StackFrame(1).GetMethod().DeclaringType.Name);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            stackTest s = new stackTest();
            s.Test();
            Console.WriteLine("Doing Test2");
            s.Test2();
            Console.ReadLine();

        }
    }

We should get Program to the console twice, and when you run within the debugger you do. When you run without the debugger in release mode, you get the output from the first Test function. Which is probally because it is to complex to be inlined; however, the second method causes a null reference exception.

Another danger with this code is that at MS improves the JIT compiler what might have worked in 2.0 could crash and burn in future versions.

JoshBerke
A: 

Hey, just as a hind

you can do

if(null == object)

to avoid getting an NullReferenceException whereas

if(object == null)

will throw one.

The NullRefEx is only thrown if the first parameter is not nullable and null because of referencing not to an object, i think. If the object is nullable, there should no NullrefEx be thrown.

asymetrixs
TheXenocide