C# 自动引用分配 - 使引用为空

发布于 2024-08-18 14:58:08 字数 521 浏览 2 评论 0原文

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

    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

关于如何实现此目的有什么想法吗?

谢谢

The C# scripting environement in Unity3D (runned under Mono) has a nice behavior when detroying objects. All the references that point to the destroyed object gets automaticly null :

    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");    

Output :

    ref1 is not null
    ref1 is null
    ref2 is null

Any ideas on how to acheive this ?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

死开点丶别碍眼 2024-08-25 14:58:08

也许相等运算符已被覆盖?这可以解释你的评论:“只要发现如果 ref1 和 ref2 不是 GameObject 而是 System.Object,那么它就不起作用。”

Maybe the equality operator has been overridden? That'd explain your comment: "Just find out that if ref1 and ref2 were not a GameObject but instead a System.Object, then it wouldn't work."

享受孤独 2024-08-25 14:58:08

Unity3D (ab) 可能使用运算符重载 + 某种内部标志,例如 bool isDeleted;,以便当 isDeleted 设置为 true 时> 在 DestroyImmediate 函数中,针对 null 的相等性测试将产生 true

It is possible that Unity3D (ab)uses operator overloading + some a kind of internal flag like bool isDeleted; so that when isDeleted is set to true in the DestroyImmediate function then the equality test against null yields true.

乖乖 2024-08-25 14:58:08

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

事实上,.NET 中没有可访问但已销毁(即释放)托管对象的有用概念(好吧,忽略 WeakReference,这实际上并不重要)。该对象要么无法访问,要么无法被销毁。

You can't do this in C# with call by value parameters. You'll have to use ref parameters which require ref keyword at call site too.

In fact, there's no useful notion of a reachable but destroyed (i.e. deallocated) managed object in .NET (well, ignoring WeakReference which doesn't really count). Either the object is not reachable or it can't be destroyed.

说谎友 2024-08-25 14:58:08

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

This is not possible in "regular" .NET, it's just not how the CLR works.

无声无音无过去 2024-08-25 14:58:08

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

While an interesting academic challenge, it's not worth pursuing from a technical standpoint. You're looking at this from the wrong angle - the CLR manages the lifetime of objects for you. The only way you could set all "variables" to null is if you passed all of the variables using the "ref" parameter modifier to your destroy method. Unless you plan on writing your whole program inside a single method, you're barking up the wrong tree. Properly structured classes and methods will ensure variables going out of scope get "nulled out," releasing the targeted object for garbage collection.

魄砕の薆 2024-08-25 14:58:08

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

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

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

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

You could add an intermediary class (proxy) that holds the reference to the actual class.

All your refs would be to this new GameObjectProxy. This would provide the same API as the GameObject, and just forward any calls on it to the underlying GameObject object.

The GameObjectProxy would also offer extra methods - to destroy the underlying GameObject, and to query if the GameObject is null. (And these could possibly be built into operator= and operator== if you want to be really evil)

Bear in mind that this approach may reduce performance, as every call to the GameObject has to be redirected through the proxy. It is also somewhat evil - it will confuse programmers who expect their references to behave "normally".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文