【问题标题】:How can I return a reference to an object that does not yet exist?如何返回对尚不存在的对象的引用?
【发布时间】:2012-03-04 14:28:28
【问题描述】:

假设我有一门课:

    class MyClass
    {
        object AnObject;

        public object GetObject(BlackBoxObjectMaker ObjMaker)
        {
            if(AnObject == null)
                AnObject = ObjMaker.MakeObject(); //MakeObject may call GetObject on this MyClass instance 

            return AnObject;
        }
    }

谁的工作是通过 GetObject() 使用 BlackBoxObjectMaker“按需”创建对象并提供对对象的访问。

还可以说,可以调用 MyClass 来提供对象“x”,其成员包含引用“x”的成员。

在这种情况下,GetObject() 最终会在同一个 MyClass 实例上调用自身,从而导致堆栈溢出。

可以修改 MyClass 以检测 GetObject() 何时在同一实例上调用自身,但在这种情况下,GetObject() 如何返回对 BlackBoxObjectMaker 尚未完成的 AnObject 的引用?

如何在引用某个对象之前提供对该对象的引用? C# 中是否有“占位符”之类的东西?

A likely duplicate, but apart from Will A's comment I cannot see anything as relevant to the context in this question

额外信息:

这是序列化工具的一部分,旨在支持循环引用。正如 Henk Holterman 所说,在这种特殊情况下,可以重新编写工具,以便在填充对象属性之前获取对对象的引用(并且需要引用);但我想回答这个问题,比如当 BlackBoxObjectMaker 真的是是一个黑盒子的时候。
这在 C++ 中是微不足道的,所以我很好奇 C# 中有哪些可用选项。

【问题讨论】:

  • 在 C++ 中怎么会是微不足道的?我很难看到。
  • @Henk 好吧,也许微不足道这个词太强了,但在 C++ 中 AnObject 将是一个指针,我可以在初始化完成之前返回,并且当 ObjMaker 完成构建 AnObject 的“真实”实例时我会将它复制到我分发的原始 AnObject 指针所指向的内存中。 (我知道这使帖子中没有详细说明假设,但我在询问 C# 功能并试图将其提炼为最简单的示例案例,所以希望它会被原谅!)

标签: c# .net design-patterns reference


【解决方案1】:

// MakeObject 可以在这个 MyClass 实例上调用 GetObject

这是你的根本问题。与其尝试完成这项工作,不如在此处修复您的解决方案设计。

还可以说,可以调用 MyClass 来提供对象“x”,其成员包含引用“x”的成员。

没问题,只要这些成员是第二个实例化的。

简而言之,这里似乎没有理由使用递归。如果您认为有,请尝试使其(很多)更清晰。

C# 中是否有“占位符”之类的东西?

不是真的。您可以制作自己的包装器,但很难获得并正确使用它。类似于(但不完全是)弱引用。

【讨论】:

  • 同意。问题在于设计。如果消费者可以在 AnObject 设置之前引用它,那么消费者需要准备在 AnObject 为 null 时进行处理。
  • @Henk 和 Bob,我已经为问题添加了更多细节 - 我也同意我的“真正”问题将通过重新设计来解决,但我仍然想知道是否有一个功能我不知道的语言 - 仅仅因为你知道一种方法来做它不是停止学习的借口;)
  • @sebf 您提到这是序列化工具的一部分。如果在该工具需要此属性时,它没有设置,那么有一个指向它的指针有什么帮助?是不是已经太晚了?
  • @Bob,该工具将需要该属性,只要为其设置“当前反序列化”对象的属性即可。 IE。在 C++ 中,您可以拥有一个对象,该对象的成员是指向其他对象的指针 - 只要您知道 where 将要到达的位置,您就可以在不知道该对象将是什么的情况下设置该成员是(或者,至少在你可以移动它的地方......)
  • @sebf 托管代码中没有“位置”。垃圾收集器可以随心所欲地在内存中移动对象(pinned 对象除外)。
【解决方案2】:

除了Henk Holterman said,你可能还想考虑使用Lazy

【讨论】:

    【解决方案3】:

    为什么不在 BlackBoxObjectMaker 类中提供静态方法 MakeObject()?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 2019-05-23
      相关资源
      最近更新 更多