我有一个由几个对象定期调用的类。 我希望在任何例外中包含信息,如对象的创建者。 我有什么选择?
“谁”是指对象或类
答案 0 :(得分:4)
调用构造函数时存储堆栈跟踪。这与SlimDX在调试版本中的作用类似。
答案 1 :(得分:2)
我可能会遗漏一些东西,但我很确定你能做到的唯一方法就是手动传递这些信息,fe。在你的对象的构造函数中 编辑:如果这是你想要的? :
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();
}
答案 2 :(得分:2)
如果仅用于调试目的,则将一个本地字符串字段添加到类中,并在类构造函数中为其指定Environment.StackTrace
。然后,您也可以将信息包含在例外中。
答案 3 :(得分:1)
一种选择是将“父”引用放入对象中:
MyObject myObj = new MyObject(this);
然后使用它。
答案 4 :(得分:1)
您可以尝试从对象的构造函数中的堆栈跟踪中收集一些信息。您可以获得堆栈帧StackTrace.GetFrames。然后,您可以遍历堆栈并尝试获取方法所属的类型。如果该类型与对象的类型不同,则停止行走并将该类型信息存储在对象中。然后,当发生异常时,您可以包含该信息以及异常。
请注意,这会增加实例化对象的成本。所以你应该考虑这个,并且可以放入一个机制来启用/禁用它或仅在调试版本中包含那段代码。
答案 5 :(得分:1)
这个问题有点含糊不清;这真的取决于你想要什么。这是调试版本的调试信息,还是一直存在的东西?
如果只是在发布的产品中删除了,我会建议做这样的事情来减少你班级的污染:
将创建移动到工厂并将堆栈检查代码放在那里。这样,创建的类不需要关心堆栈框架内容;它隐藏在工厂里。
如果您不介意有点污染,可以通过属性设置器注入信息,或者您可以让工厂更新已创建实例的列表+每个实例的关联创建信息。然后,您可以查询此列表,直到您满意为止。最后,在发布版本中,您可以使用几个#ifdefs删除所有这些功能。
答案 6 :(得分:0)
我建议使用StackTrace
对象和/或GetFrame
方法。我没有尝试过,但它应该做你需要做的事情而不必改变对象的每个实例化(假设你没有使用工厂)。
我会想象similar to this会起作用。
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
另请注意,这似乎是“不完全”重复,但它接近上面链接的问题。
答案 7 :(得分:0)
这样的东西可以起到调用类型的作用:
public class Foo
{
private Type ParentAtCreation = null;
public Foo()
{
ParentAtCreation = (new StackTrace())
.GetFrame(1)
.GetMethod()
.DeclaringType;
}
}
答案 8 :(得分:0)
您可以对该类使用重载构造函数,并使用全局变量来存储您在该重载构造函数中接收的对象
例如,如果在调用要创建的对象时需要winforms中的类对象,则使用重载构造函数来接收表单对象
并在构造函数中使用此对象将其值存储在全局变量中,如
当您在此情况下声明对象时,我使用表单使用我当前运行的表单打开
Admin_Login ad = new Admin_Login(Enrol, this);
ad.Show();
this.Visible = false;
并使当前表单不可见,以便在需要时再次调用它。我现在不能将它作为新表格的父母处理
在Admin_Login表单中我有一个重载的构造函数
public Admin_Login(string Enrol,Form parent)
{
Enrollment = Enrol;
Parent = parent;
InitializeComponent();
}
其中Parent是Form
的全局变量B.O.L
答案 9 :(得分:0)
我很惊讶没有人说过这个,即使是对他们自己的解决方案的一个警告,所以我会:这通常是一个坏主意,如果你发现自己需要这样做,那通常是一个巨大的指标你的设计出了什么问题。如果你沿着这条路走下去解决问题,最终会导致更大的问题。最好退两步,修复设计,这是必要的。