C# 引用并将它们设置为 null

问题描述 投票:0回答:1

我有这个代码。

public class Application
    {
        HybridObject obj;

        public Application()
        {
            obj = new HybridObject().Core;
            obj.Delete();

            while (true)
            {
                Update();
            }
        }

        void Update()
        {
            if (obj == null) Console.WriteLine("Destroyed"); // I NEED THIS TO WORK
            if (obj.Core == null) Console.WriteLine("Destroyed Core"); // THIS WORKS
        }
    }
public class HybridObject
    {
        protected HybridObject core;
        public HybridObject Core => core;

        public HybridObject()
        {
            this.core = this;
        }

        public void Delete()
        {
            this.core = null;
        }
    }

我想要实现的是...在 Application 类构造函数中,我创建了一个新的 HybridObject 实例,然后我想将 obj 属性设置为 HybridObject 实例的 Core 属性,而不是 HybridObject 本身。这样,调用obj.Delete()时,会将HybridObject的Core属性设置为null,Application中的obj属性也会反映这一变化。

但我无法让它工作,我真的很挣扎。我希望这是有道理的。

任何代码示例都是超级的,因为我一天中的大部分时间都没有解决方案

谢谢!!

c# .net-7.0
1个回答
1
投票

你不明白这一切是如何运作的:

首先,你有这个代码:

public class Application
{
    HybridObject obj;

    public Application()
    {
        obj = new HybridObject().Core;
        obj.Delete();

        while (true)
        {
            Update();
        }
    }

    void Update()
    {
        if (obj == null) Console.WriteLine("Destroyed"); // I NEED THIS TO WORK
        if (obj.Core == null) Console.WriteLine("Destroyed Core"); // THIS WORKS
    }
}

您的

obj
是您的
Application
班级的私有成员字段。它永远不会去
null
除非你将它设置为空。如果你在它上面调用
Delete
并不重要,它将永远引用你告诉它引用的对象(直到你告诉它引用另一个对象(通过赋值)或将它设置为
null
(也通过赋值) .

然后你有这个相当奇怪的类:

public class HybridObject
{
    protected HybridObject core;
    public HybridObject Core => core;

    public HybridObject()
    {
        this.core = this;
    }

    public void Delete()
    {
        this.core = null;
    }
}

这个类的实例可以有两种状态,normaldeleted。您的

Core
属性(及其支持
core
字段)可以指向整个对象(normal(或新建)状态,也可以将其设置为
null
deleted 状态). 这有点奇怪,但很好。

但是,在任一状态下,一旦不再有任何对您的

HybridObject
类实例的引用,该特定实例就有资格进行垃圾回收。在 normal 状态下,该实例将持有对其自身的硬引用并不重要(因为符合收集条件的对象不会采取行动使它们引用的对象保持活动状态)。一旦一个对象符合收集条件,它将在下一次 GC 中被收集(提供或采取一些不影响程序逻辑的复杂规则)。

这种循环引用在像 C 或 C++ 这样的语言中是一个真正的 PITA(你必须仔细遍历你创建的对象图才能删除它们),或者在像基于 COM 的引用计数框架中(预.NET) Visual Basic。 .NET GC 把这些情况当成了早餐。

只需接受您无需担心删除所有内容(在超过 99% 的情况下)并过着垃圾收集的生活方式。

© www.soinside.com 2019 - 2024. All rights reserved.