想象一下,你有一个具有多个属性的对象。其中一个属性是字符串:
private class MyObject
{
public string PropertyOne {get; set;}
...
}
我现在根据MyObject
上的内容创建一个新对象:
private class MySecondObject
{
public string PropertyOneCopy {get; set;}
public MySecondObject(MyObject myObject)
{
this.PropertyOneCopy = myObject.PropertyOne;
....
}
}
在调用场景中,我们有:
private class Scenario
{
private MySecondObject _mySecondObject;
public void Go()
{
MyObject myObject = new MyObject();
myObject.PropertyOne = "Hello, World!";
_mySecondObject = new MySecondObject(myObject);
}
}
MyObject的原始实例现在不属于范围。 _mySecondObject是long -living。
我的问题是......原始的MyObject会被垃圾收集吗?如果我使用this.PropertyOneCopy = String.Copy(myObject.PropertyOne);
吗?
答案 0 :(得分:3)
以前在myObject
中的对象将被正常垃圾收集,因为没有未完成的引用。
仍有对string
对象的引用,该对象曾是PropertyOne
的{{1}}属性的值,但这只会阻止字符串从被回收,而不是整个myObject
实例。
MyObject
没有什么特别的,只是作为一个接受String.Copy
实例的构造函数并创建一个重复的对象(string
没有这样的构造函数)。
答案 1 :(得分:2)
肯定会收集垃圾。即使你不使用String.Copy。
字符串没有引用任何其他对象...相反,你拥有的是一个对象,它引用了一个字符串...该字符串发生的事情与引用该字符串的对象无关字符串。
示例:的
如果你有对象A,B和C,它们都有一个像这样分配的字符串属性:
string s = "str";
A.Str = s;
B.Str = A.Str;
C.Str = B.Str;
与做:
相同string s = "str";
A.Str = s;
B.Str = s;
C.Str = s;
当A不再使用时,即使它们共享相同的字符串,它也可能在不影响其他对象的情况下死亡。
答案 2 :(得分:1)
原始的MyObject会被垃圾收集吗?
是的,它只有传出引用。什么都没有让它远离GC。
"Hello, World!"
字符串是共有的,只要其中一个对象处于活动状态,它就会保持活动状态。
使用GC比你想象的要容易,你几乎不需要'帮助'。
答案 3 :(得分:0)
.NET垃圾收集器将回收任何引用无法访问的对象使用的内存。 MyObject
退出时,Go
的引用会消失,使MyObject
的实例可以进行垃圾回收。 MyObject
引用一个也存储在MySecondObject
中的引用的字符串没有任何区别。
答案 4 :(得分:0)
MySecondObject对MyObject中的字符串有引用,而不是对MyObject-object本身的引用,因此一旦退出Go函数,myObject就会被释放到GC,所以不必担心。
如果您以这种方式实现,那么myObject将在MySecondObject发布之前一直未发布:
private class MySecondObject {
private MyObject myObject;
public string PropertyOneCopy {
get{
return myObject.PropertyOne;
}
}
public MySecondObject(MyObject myObject) {
myObject = myObject.PropertyOne;
....
}
}