【问题标题】:C# Automatic references assignment - making references nullC# 自动引用分配 - 使引用为空
【发布时间】:2010-01-24 21:35:20
【问题描述】:

Unity3D 中的 C# 脚本环境(在 Mono 下运行)在销毁对象时具有良好的行为。所有指向被破坏对象的引用都自动变为空:

    GameObject ref1 = (GameObject)Instantiate(obj);
    GameObject ref2 = ref1;

    if (ref1 != null)
        Debug.Log("ref1 is not null");

    DestroyImmediate(ref1);

    if (ref1 == null)
        Debug.Log("ref1 is null");

    if (ref2 == null)
        Debug.Log("ref2 is null");    

输出:

    ref1 is not null
    ref1 is null
    ref2 is null

关于如何实现这一点的任何想法?

谢谢

【问题讨论】:

  • 只要发现 ref1 和 ref2 不是 GameObject 而是 System.Object,那么它就行不通了。

标签: c# reference variable-assignment


【解决方案1】:

也许相等运算符已被覆盖?这可以解释您的评论:“只要找出如果 ref1 和 ref2 不是 GameObject 而是 System.Object,那么它就行不通了。”

【讨论】:

  • 这是否意味着他们在调用 DestroyImmediate 时将“Destroyed”标志设置为 true。然后在 == 运算符中,他们会在与 null 比较时检查此标志?
【解决方案2】:

Unity3D (ab) 可能使用运算符重载 + 某种内部标志,例如 bool isDeleted;,因此当 isDeletedDestroyImmediate 函数中设置为 true 时,对 @987654325 的相等性测试@ 产生 true

【讨论】:

  • 对了,你为什么说“收益”而不是“回报”?
  • 他指的不是yield这个关键字,而是这个词的正确用法:)
【解决方案3】:

您不能在 C# 中使用按值调用参数执行此操作。您还必须在调用站点使用 ref 参数,这些参数也需要 ref 关键字。

事实上,.NET 中没有可访问但已销毁(即解除分配)托管对象的有用概念(好吧,忽略 WeakReference 这并不重要)。对象不可访问或无法销毁。

【讨论】:

  • 并且他必须将所有引用该对象的变量传递给他的 Destroy 方法...哎呀。
【解决方案4】:

这在“常规”.NET 中是不可能的,这不是 CLR 的工作方式。

【讨论】:

  • Unity 仍然是 C#,它们在 Mono 上运行。你认为他们为了他们的目的改变了一些 Mono 行为吗?
  • 我很确定,虽然 unity3d 是基于 Mono 的,但他们对其进行了重大修改。毕竟,unity3d 早在单点触控之前就支持 iPhone。
【解决方案5】:

虽然是一项有趣的学术挑战,但从技术角度来看并不值得追求。您从错误的角度看待这个问题 - CLR 为您管理对象的生命周期。将所有“变量”设置为 null 的唯一方法是使用“ref”参数修饰符将所有变量传递给您的销毁方法。除非您打算在单个方法中编写整个程序,否则您会找错树。结构正确的类和方法将确保超出范围的变量被“清空”,释放目标对象以进行垃圾回收。

【讨论】:

  • 我理解你的意思,但我的目的不是争论这是否是一个好的设计。我只是好奇他们是怎么做到的。
  • 好吧,我想我误解了 unity3d - 我认为它是一种看起来像 c# 的脚本语言,但我现在看到它 c#。我和你一样感兴趣:)
【解决方案6】:

您可以添加一个中间类(代理)来保存对实际类的引用。

您的所有参考都将指向这个新的 GameObjectProxy。这将提供与 GameObject 相同的 API,并将对它的任何调用转发到底层 GameObject 对象。

GameObjectProxy 还将提供额外的方法 - 销毁底层 GameObject,并查询 GameObject 是否为空。 (如果你真的很邪恶,这些可能会被内置到 operator= 和 operator== 中)

请记住,这种方法可能会降低性能,因为对 GameObject 的每次调用都必须通过代理重定向。这也有点邪恶——它会让那些期望他们的引用行为“正常”的程序员感到困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 2021-06-28
    • 2013-11-15
    • 1970-01-01
    相关资源
    最近更新 更多