如何确定谁是对象的创建者

时间:2009-08-30 13:55:55

标签: c# .net

我有一个由几个对象定期调用的类。 我希望在任何例外中包含信息,如对象的创建者。 我有什么选择?

“谁”是指对象或类

10 个答案:

答案 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)

我很惊讶没有人说过这个,即使是对他们自己的解决方案的一个警告,所以我会:这通常是一个坏主意,如果你发现自己需要这样做,那通常是一个巨大的指标你的设计出了什么问题。如果你沿着这条路走下去解决问题,最终会导致更大的问题。最好退两步,修复设计,这是必要的。