Reputation: 11025
I have two classes as follow:
First one:
class Class1
{
private void Method1()
{
var obj=new TestClass();
obj.TestMethod1();
}
}
Second One:
class TestClass
{
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
//get the calling class
}
}
When Class1.Method1
calls TestClass.TestMethod1
which in turn calls TestClass.TestMethod2
, I want to get the fully qualified class name of Class1
inside TestClass.TestMethod2
. I have seen this link, but I think I will get TestClass.TestMethod1
as method name and TestClass
as the class name. How can I get the calling class name?
Upvotes: 1
Views: 2577
Reputation: 10427
This will get the Type
that first called TestClass
. It prints:
TestStack.Class1
TestStack.Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace TestStack
{
class Class1
{
public void Method1()
{
var obj = new TestClass();
obj.TestMethod1();
}
}
class TestClass
{
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
StackTrace st = new StackTrace();
Type calling = null;
foreach (var sf in st.GetFrames())
{
var type = sf.GetMethod().DeclaringType;
if (type != this.GetType())
{
calling = type;
break;
}
}
Console.WriteLine(calling);
}
}
class Program
{
static void Main(string[] args)
{
Class1 class1 = new Class1();
class1.Method1();
TestClass testClass = new TestClass();
testClass.TestMethod1();
}
}
}
Upvotes: 0
Reputation: 3709
You might check out this code to find your solution without having to pass class instances or type parameters, etc....:
class Program
{
static void Main(string[] args)
{
var c = new Class1();
c.Method1();
}
}
class Class1
{
public void Method1()
{
var obj = new TestClass();
obj.TestMethod1();
}
}
class TestClass
{
public void TestMethod1()
{
TestMethod2();
var mth = new StackTrace().GetFrame(1).GetMethod();
var clss = mth.ReflectedType.Name;
Console.WriteLine("Classname in Method1(): {0}", clss);
}
private void TestMethod2()
{
//get the calling class
var mth = new StackTrace().GetFrame(1).GetMethod();
var clss = mth.ReflectedType.Name;
Console.WriteLine("Class in .Method2(): {0}", clss);
}
}
Upvotes: 0
Reputation: 14608
Could you not pass the type into the second class via constructor like:
class Class1
{
private void Method1()
{
Type t = typeof(Class1);
var obj = new TestClass(t);
obj.TestMethod1();
}
}
class TestClass
{
private Type _caller;
public TestClass(Type type)
{
_caller = type;
}
public void TestMethod1()
{
TestMethod2();
}
private void TestMethod2()
{
//Do something with the class
}
}
Upvotes: 1
Reputation: 1062530
There is no nice way to do that. You can access the stack-frames (just look at the second frame, rather than the first) - but that is expensive and brittle. You could use optional caller-member-name attributes (being explicit from TestMethod1
) to get hold of "Method1"
, but not the "Class1"
part. One other option would be to pass in an object (or just the name) explicitly; for example:
private void Method1()
{
var obj=new TestClass();
obj.TestMethod1(this);
}
public void TestMethod1(object caller=null,
[CallerMemberName] string callerName=null)
{
TestMethod2(caller??this,callerName??"TestMethod1");
}
private void TestMethod2(object caller=null,
[CallerMemberName] string callerName=null)
{
string callerName = ((caller??this).GetType().Name) + "." + callerName
//get the calling class
}
but I have to confess that is pretty ugly
Perhaps better would be to question why you need this in the first place.
Upvotes: 7