将实例设置为null而不是引用它的变量。

5
我创建了一个对象,并将它分别赋值给两个不同类中的变量。
如果在一个类中将该变量设置为null,则只会断开该变量对该对象的引用,但该对象本身仍然存在于另一个引用中。
我如何将对象设置为null,以便两个引用都指向null?而不是找到每个引用。
这是伪代码。想法是在ClassA(ref1)和ClassB(ref2)中失去对该引用的控制。
public class ClassA
{
    public ClassC ref1 = new ClassC ();

    static void Main(string[] args)
    {
        ref1 = null;
    }

}

public class ClassB
{
    public static ClassC ref2;

    public static AssignC (ClassC c)
    {
        ref2 = c;
    }

}

public class ClassC
{

    public ClassC ()
    {
        ClassB.AssignC (this);
    }

}

5
创建一个封装现有对象的另一个对象。 - qxg
1
你为什么想要这样做? - EagleBeak
1
也许弱引用可以帮助解决问题,但由于您没有提供详细的问题描述,我不能确定。 - Ilya Ivanov
1
@qxg:如果存在内部类的引用(例如附加的事件处理程序等),则仍然不会失去对内部类的所有引用。 - Patrick Hofman
4
如果两个类对象持有对同一个成员的引用,试图从其中一个对象清除该成员会打破封装范例。第二个对象不知道它的成员已被置空。 - Tarec
显示剩余5条评论
3个回答

4

你不能这样做。

你不能直接访问另一个类的内部,(好吧,通常情况下不行)。这种封装形式使得 .Net 代码更容易调试。

你可以在该类上编写一个函数,将其所有成员设置为null,你可以将其作为IDisposable的实现来完成。

当没有引用指向对象时,垃圾回收器会回收内存,你无法直接控制它。


你可以像这样重新编写你的示例。

public class A
{
    private C c = new C();

    static void Main(string[] args)
    {
        c.Dispose();
        c = null;
    }
}

public static class B
{
    private static C c;

    public static LastC
    {
        get
        {
            return c;
        }

        set
        {
           c = value;
        }
    }
}

public class C : IDisposable
{       
    public C()
    {
        B.C = this;
    }

    public void Dispose()
    {
        if (B.LastC == this)
        {
            // LastC has not been set by another instance.
            B.LastC = null;
        }
    }
}

你会注意到我通过一个setter方法使静态引用可访问,这样其他类就可以访问它。

2

将 null 赋值给引用类型变量只会改变该特定变量 - 对象的引用的值。Jon Skeet 的这篇好文章详细介绍了这个问题 - http://www.yoda.arachsys.com/csharp/parameters.html

在您的情况下,最好将对象封装到 Singleton 模式中。因此,将 null 赋值给主变量将销毁对对象的唯一引用,并且可以进行垃圾回收。


1
这个 Jon Skit 是谁?;p - leppie

2

这是不可能的。

引用可以是null或指向实际实例。当你进行赋值操作,例如ref2 = c;时,一个引用的值被复制到另一个引用中。之后,你就有了两个引用指向同一个实例。(实例肯定没有被复制,只有引用被复制;这些都是引用类型。)

当你执行ref1 = null;时,这只是用指向“无”的引用覆盖了特定的引用。它并不会销毁任何实例,只是使单个引用“指向”其他东西。其他引用不受影响(方法参数使用refout在当前执行的方法中可能实际上是相同的引用,即转向其他地方的引用)。

在问题标题中,你说“将实例设置为null”,但这并没有什么意义,因为实例是一个对象(而不是引用)。

那么如何销毁一个实例?你不能。垃圾收集器可能会在某个时刻(当你要分配新对象时)检查到某些实例没有被引用。然后它将从内存中删除这些实例。

你不能“清零”其他人的引用。仅仅因为你有一个指向实例的引用,没有办法说“搜索整个应用程序并找到其他恰好指向同一实例的引用,并更改所有这些引用”。这将是一件非常糟糕的事情,因为人们永远无法确定他们的变量何时会突然改变。


谢谢,这是一个很好的回复! - user2994682

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接