I have a class that is called regularly by several objects. I would like to include information in any exceptions as who the creater of the object is. What are my options?
"Who" refers to an object or class
I have a class that is called regularly by several objects. I would like to include information in any exceptions as who the creater of the object is. What are my options?
"Who" refers to an object or class
Store a stacktrace when the constructor is called. This is similar to what SlimDX does in debug builds.
I might be missing something, but I am pretty sure that the only way you can do it, is by manually passing this information, fe. in constructor of your object.
Edit : If this is what you were looking for? :
class Creator
{
public string Name { get; private set; }
public Creator(string name)
{
Name = name;
}
}
class Foo
{
readonly Creator creator;
public Foo(Creator creator)
{
this.creator = creator;
}
public void DoSth()
{
throw new Exception("Unhandled exception. My creator is " + creator.Name);
}
}
public static void Main()
{
Foo f = new Foo(new Creator("c1"));
f.DoSth();
}
If it's only for debugging purposes then add a local string field to the class and assign Environment.StackTrace
to it in the class constructor. Then you can include the information in the exceptions as well.
One choice would be to put a "parent" reference into the object:
MyObject myObj = new MyObject(this);
and then use that.
You can try to gather some information from the stack trace in the constructor of your object. You can get the stack frames StackTrace.GetFrames. Then you can walk the stack and try to get the type that a method belongs. If that type is different than the type of your object, you stop walking and store that type information within your object. Then when an exception occurs, you can include that information along with the exception.
Note that this will increase the cost of instantiating your object. So you should consider that and may be put in a mechanism to enable/disable it or include that piece of code only in the debug build.
The question is slightly ambiguous; it really depends what you want. Is this debug information for debug builds, or is it something you will always keep around?
If it's just debug cruft that will be removed in the released product, I'd suggest doing something like this to reduce the pollution of your class(es):
Move the creation into a factory and put the stack inspection code there. This way, the created class doesn't need to care about the stack frame stuff; it is hidden away in the factory.
You can then inject the information via a property setter if you don't mind a little pollution or you could have the factory update a list of created instances + associated creation information for each instance. You can then query this list til your heart is content. Finally, in the release build, you can remove all of this functionality with a couple of #ifdefs.
I'd recommend using the StackTrace
object and/or it's GetFrame
method. I haven't tried it but it should do what you need it to do w/o having to change every instantiation of the object (assuming you're not using a Factory).
I would imagine something similar to this would work.
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
Also note that this appears to be "not quite" a duplicate, but it's close to the question linked above.
Something like this could work to get the calling type:
public class Foo
{
private Type ParentAtCreation = null;
public Foo()
{
ParentAtCreation = (new StackTrace())
.GetFrame(1)
.GetMethod()
.DeclaringType;
}
}
You can use overloaded constructor to that class and a global variable to store that object you receive in that overloaded constructor
e.g if you want an object of class in winforms when you invoke the object to be created you use a overloaded constructor that receives an object of a form
and in the constructor you use this object to store its value in global variable like
When you declare the object as in this case i use a form to open using my currently running form then
Admin_Login ad = new Admin_Login(Enrol, this);
ad.Show();
this.Visible = false;
and make the current form not visible to invoke it again when i want it. I cant dispose it as its the parent of the new form now
and in Admin_Login form i have an overloaded constructor
public Admin_Login(string Enrol,Form parent)
{
Enrollment = Enrol;
Parent = parent;
InitializeComponent();
}
where Parent is my global variable of Form
B.O.L
I'm surprised no one else has said this yet, even as a caveat to their own solution, so I will: this is generally a bad idea, and if you find yourself needing to do it, that's usually a huge indicator that something is very wrong with your design. If you go down this route to solve your problem, you will end up causing far larger issues down the road. Best to take 2 steps back and fix the design that is making this necessary.