C# 将对对象的所有引用设为null,以便可以收集该对象
我正在尝试实现类似Unity3D中的C# 将对对象的所有引用设为null,以便可以收集该对象,c#,C#,我正在尝试实现类似Unity3D中的GameObject的行为 在任何给定的应用程序中,我有很多很多对象,它们引用任何给定数量的其他对象。每个对象都可以标记为删除,并在删除时进行标记;我需要知道如何取消对它的任何引用,以便它可以被GC收集并从范围中完全删除。我不是在寻找一种伪造的方法,就是在寻找一种实际的方法 出于所有意图和目的;如果一个对象引用另一个对象,并且被引用的对象被销毁,我需要该引用显示为null。如果我做不到这一点,那么我唯一的其他选择就是每次使用它们时检查每个引用,并手动评估它是否
GameObject
的行为
在任何给定的应用程序中,我有很多很多对象,它们引用任何给定数量的其他对象。每个对象都可以标记为删除,并在删除时进行标记;我需要知道如何取消对它的任何引用,以便它可以被GC收集并从范围中完全删除。我不是在寻找一种伪造的方法,就是在寻找一种实际的方法
出于所有意图和目的;如果一个对象引用另一个对象,并且被引用的对象被销毁,我需要该引用显示为null。如果我做不到这一点,那么我唯一的其他选择就是每次使用它们时检查每个引用,并手动评估它是否已被销毁,这是不实际的。您不能将
此
(也称为“您自己”)设置为null
,这样对您的引用将丢失/销毁<代码>此为只读
您可以使用事件告诉引用实例的人将其设置为
null
。在将实例设置为null
时,不要忘记取消订阅事件处理程序。我知道有两种方法与您描述的方法非常接近:
方法1:WeakReference
仅使用WeakReference
引用对象,保留硬引用的“DataManager
”除外
然后,您可以通过清除DataManager
的硬引用来“标记”垃圾收集实例
public class DataManager
{
private readonly HashSet<object> data = new HashSet<object>();
public void RegisterInstance(object instance)
{
data.Add(instance);
}
public void FreeInstance(object instance)
{
data.Remove(instance)
}
}
public class Foo
{
List<WeakReference<Bar>> bars = new List<WeakReference<Bar>>();
private readonly DataManager dataManager;
public Foo(DataManager dataManager)
{
this.dataManager = dataManager;
}
public void LogSomething()
{
bars.Add( Bar.Create(dataManager, 3, "Susan"));
bars.Add( Bar.Create(dataManager, 4, "Bob"));
bars.Add( Bar.Create(dataManager, 0, "Megan"));
dataManager.FreeInstance(bars[1]);
CG.Collect();
for(int i = bars.Count - 1; i >= 0; i--;)
{
// hard reference to not loose the reference target between now and logging
Bar bar;
if(!bars[i].TryGetTarget(out bar)
{
bars.RemoveAt(i);
continue;
}
Debug.Log($"{bar.value.Data2} has {bar.value.Data1} chocolate bars");
}
}
}
public class Bar
{
public int Data1 { get; private set; }
public string Data2 { get; private set; }
private Bar(int data1, string data2)
{
Data1 = data1;
Data2 = data2;
}
public static WeakReference<Bar> Create(DataManager dataManager, int data1, string data2)
{
var bar = new Bar(data1, data2);
dataManager.RegisterInstance(bar);
return new WeakReference(bar);
}
}
您还可以覆盖Wrapper
的equals
方法,以实现以下行为:
var bar = new Wrapper<Bar>(null);
var isWrappedValueNull = bar == null;
// overwrite 'equals' if you want isWrappedValueNull to be true in this case
var bar=新包装(空);
var isWrappedValueNull=bar==null;
//如果希望在本例中isWrappedValueNull为true,请覆盖“equals”
我是用android应用程序写的-示例代码可能有一些小错误@user2312610:很抱歉,但我很确定这在.NET中是不可能的。你能举一个更详细的例子吗?@user2312610那些拥有多年.net经验的人很高兴地告诉你,你误解了你在unity中看到的东西。这是不可能的。你的意思是?是的,确实。根据语言规范,后者是不可能的。@user2312610:是的,如果只引用外部实例,而不引用内部实例,这会有所帮助。
var bar = new Wrapper<Bar>(null);
var isWrappedValueNull = bar == null;
// overwrite 'equals' if you want isWrappedValueNull to be true in this case