我有一个类经常被多个对象调用。 我想在任何异常中包含创建这个对象的人的信息。 我的选项有哪些?
"谁"指的是对象或类。
在构造函数调用时存储堆栈跟踪。这类似于SlimDX在调试版本中所做的操作。
[MethodImpl(MethodImplOptions.NoInline)]
进行修饰(如果我记得“拼写”正确的话)。 - Cecil Has a NameEnvironment.StackTrace
分配给它。然后您也可以在异常中包含这些信息。我可能漏掉了什么,但我非常确定你唯一能够做到的方式是手动传递这些信息,例如在对象的构造函数中。
编辑:如果这就是你要找的内容?
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();
}
MyObject myObj = new MyObject(this);
然后使用它。
你可以尝试在对象的构造函数中从堆栈跟踪中收集一些信息。你可以获取堆栈帧 StackTrace.GetFrames。然后你可以遍历堆栈并尝试获取一个方法所属的类型。如果该类型与你的对象的类型不同,你就停止遍历并将该类型信息存储在你的对象中。然后当异常发生时,你可以将该信息与异常一起包含。
请注意,这将增加实例化对象的成本。因此,你应该考虑这一点,并可能添加一个机制来启用/禁用它或仅在调试版本中包含该代码片段。
这个问题有点模糊,它真的取决于你想要什么。这是调试信息还是你总是保留它?
如果这只是在发布产品中将被删除的调试垃圾,我建议像这样做以减少类的污染:
将创建操作移到工厂中,并将堆栈检查代码放在那里。这样,创建的类不需要关心堆栈帧的内容;它被隐藏在工厂中。
如果您不介意一些污染,您可以通过属性设置器注入信息,或者您可以让工厂更新已创建实例的列表+每个实例的相关创建信息。然后,您可以查询此列表直到满意为止。最后,在发布版本中,您可以使用几个 #ifdefs 删除所有这些功能。
StackTrace
对象和/或它的GetFrame
方法。虽然我没有尝试过,但它应该可以做到你需要的事情,而不必更改对象的每个实例化(假设你没有使用工厂)。using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
还要注意的是,这似乎不完全是一个重复的问题,但与上面链接的问题很接近。
可以尝试以下代码来获取调用类型:
public class Foo
{
private Type ParentAtCreation = null;
public Foo()
{
ParentAtCreation = (new StackTrace())
.GetFrame(1)
.GetMethod()
.DeclaringType;
}
}
您可以使用重载构造函数和全局变量来存储接收到的对象。
例如,如果您想在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 是我的全局表单变量
B.O.L