Victor Mukherjee
Victor Mukherjee

Reputation: 11025

Get the name of the class where the object was created

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

Answers (4)

Ahmed KRAIEM
Ahmed KRAIEM

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

bbqchickenrobot
bbqchickenrobot

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

DGibbs
DGibbs

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

Marc Gravell
Marc Gravell

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

Related Questions