【问题标题】:get object's instance name at runtime在运行时获取对象的实例名称
【发布时间】:2013-12-05 04:37:16
【问题描述】:

我需要在运行时获取对象实例的名称。我有办法,但我认为一定有更好的办法。

假设我有 4 个表格:FormA1、FormA2、FormA2 和 DormA4。它们都源自FormA。 FormA 永远不会被实例化——假设它是虚拟的。

我也有FormB。每个 FormA 子代都可以在运行时根据特定事件实例化 FormB。 FormB 的工作是获取一些信息并在运行时将其返回给调用它(实例化它)的表单。但是在不知道调用表单实例的名称的情况下,我无法访问任何调用表单的属性。

我目前的做法是我在 FormB 中有一个构造函数,它使用 FormA 作为类型对发送者的引用作为参数,例如:

public class FormB : Form
{
   private FormA referenceForm;

   public FormB(ref FormA callingForm) 
   {
       referenceForm = callingForm;
   }
}

这样我可以让本地方法访问调用表单的属性。当然,要获得特定属性,我需要代码反射,这样我才能获得正确的类型并访问子项的特定属性。 或者,我认为,我可以创建 FormHandler 类,每次实例化子表单时实例化它并在事件中传递值,但这可能会使它变得比必要的复杂。

所以问题是,如何获取对象的实例名称以便访问其属性?

【问题讨论】:

  • 实例没有名字。

标签: c# object instance


【解决方案1】:

您尚未解释为什么以及何时需要这样做,但听起来您正在寻找发布者订阅模式。您可以为此使用委托/事件,例如 FormB 将有趣的事件发布到 FormA

public class InterstingInfo
{
    // TODO
}

public class FormB
{
    public delegate void Callback(InterstingInfo interestingData);
    public event Callback observer;

    private void NotifyObserver()
    {
        InterstingInfo interstingInfo = null;
        // TODO setup intersting data
        observer.Invoke(interstingInfo);
    }
}

public class FormA
{
    void CreateFormB()
    {
        FormB formB = new FormB();
        formB.observer += (o) => { DoStuffForOtherForm(o); };
    }

    void DoStuffForOtherForm(InterstingInfo interestingData)
    {
        // TODO - Do stuff based on 'interstingInfo'
    }
}

【讨论】:

    【解决方案2】:

    这是你想要的吗?

    obj.GetType().Name
    

    这将告诉您名称(例如 FormA1)

    顺便说一句,没有必要在你的构造函数中使用ref。

    【讨论】:

    • 更多解释为什么不需要ref:FormA 是一个类,这意味着它将通过by reference。对于结构,你真的只需要 ref。
    • 当有人说...嗯,我想打开这个罐子,你有枪我可以打开这个罐子吗?你说,你需要一个开罐器,而不是枪,这是一个开罐器。你不要走……“这是你的枪”
    • 感谢您的回复。非常有用的第二部分。
    • 您的答案的问题是获取对象名称很容易。我需要获取实例名称,以便可以访问对象特定实例的属性。
    • @user2611947 如果您使用反射,则不需要实例名称。你传入实例。
    【解决方案3】:

    这不是您问题的直接答案。但是您应该使用委托系统。在 FormB 中设置一个委托,FormB 的实例化器可以为其分配一个操作。您可以通过委托传递所需的参数。

    更多信息请参见:https://stackoverflow.com/a/639366/2696641 Where do I use delegates?

    【讨论】:

    • 这是我看待它的一种方式,但我仍然需要知道实例的名称才能传递委托。这就是为什么我在考虑使用 FormHandler 类来处理事件并通过委托传递方法。
    • 当 FormA 的子级创建 FormB 时,您可以将 FormA 中的方法分配给 FormB 中的委托。在关闭 FormB 之前完成 FormB 时调用该方法。该方法可以有一个有效载荷,它是一个数据类型类来传回信息。
    【解决方案4】:

    FormB 应该能够在任何地方被实例化,并且最好不要关心或知道是谁创建了它。对您来说更好的方法是在 FormB 中公开您需要的任何可用属性,并让调用对象读取它们。

    【讨论】:

    • 这不言而喻。您可以在任何地方实例化 FormB。但是,如果 FormB 在其 TextBox1 中获取一个字符串,并且您想在调用它的 FormA 实例的 Label1 中显示该字符串(FormB),您将如何做呢?
    • 您可以在 FormB 的 TextBox 周围包裹一个公共属性并公开它,或者您可以创建一个委托并在 TextBox 值更改时从 FormB 调用事件。如果 FormA 正在处理事件,那么您可以更新 FormA 中的标签。
    【解决方案5】:

    嗯……

    我想你是在问一个具体的答案。当你应该问将军时……我应该怎么做。

    我会将您的 FormAs 需要的所有数据从 FormB 公开为 FormB 上的属性。然后我会在 FormB 上公开一个事件,以便 FormA 知道何时从 B 填充自己。

    http://msdn.microsoft.com/en-us/library/ak9w5846.aspx

    这基本上是 GOF 观察者模式...

    【讨论】:

      【解决方案6】:

      我想最后我可以在运行时将每个 FormAs 实例化为相同的名称,而不考虑表单并引用该任意单个名称。只要我不同时实例化 FormAs。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-28
        • 2014-03-03
        • 1970-01-01
        • 2012-11-16
        • 1970-01-01
        • 2014-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多