Reputation: 5134
Is there a way in C# to detect which object invoked a method?
for example:
class Foo1
{
Foo2 m_inner = null
Foo1()
{
m_inner = new Foo2();
m_inner.Do();
}
}
class Foo2
{
Foo2()
{
}
void Do()
{
//Here I want to know that Foo1 called it.
}
}
IS it possible to know in Foo2::Do that it was called from Foo1?
Upvotes: 1
Views: 430
Reputation: 1064324
I'm adding this for completeness, but note that it does not help much in the case of a constructor, as the caller's method-name will always be .ctor
; but:
public void Do([CallerMemberName] string caller = null)
{
Console.WriteLine(caller);
}
Now, a call like:
void SomeMethod() {
someObj.Do();
}
will pass in "SomeMethod"
as caller
. As I mention, it doesn't work as well for constructors, which gives you two options:
someObj.Do("SyntheticNameHere");
Do
(seems overkill)Upvotes: 0
Reputation: 14386
There are three ways to handle this. The first is a sender object passed to the method, like that included with .Net events. This exposes the sender to the caller in a very obvious way and allows the method to call back to the sender. However, if the code is security sensitive (for example, ensure this method is only called from library X), this is not suitable.
The second way is the System.Diagnostics.StackTrace class. See See How do I get the current line number? for an example of its use. You can examine the calling type and assembly from the metadata.
The third, if you do not mind adding optional arguments to the method, is using the CallerMemberName and CallerFilePath attributes. However, this is probably not what you want here. This works through obfuscation, unlike the StackTrace method, however.
Upvotes: 1
Reputation: 6444
Any reason you can't use a sender object, similarly to an event?
class Foo2
{
Foo2() {}
void Do(object sender)
{
if(sender is Foo1)
Console.Writeline("Sent from Foo1");
}
}
Usage
class Foo1
{
Foo2 m_inner = null
Foo1()
{
m_inner = new Foo2();
m_inner.Do(this);
}
}
Upvotes: 1
Reputation: 13874
The 'proper' way to do this would to be to alter the signature of Do:
void Do(object sender)
Then when called:
m_inner.Do(this);
Otherwise you're going to be using the call stack and some reflection.
Upvotes: 1