If I have a method like:
public SomeObject GetObject(int ID){
SomeObject obj1 = new SomeObject();
obj1.ID = ID;
return obj1;
}
Then if I used the method like this:
SomeObject obj2 = GetObject(4);
Will ob开发者_JAVA百科j2
simply be a reference in memory to obj1
, or will it be copied in memory and two complete objects exist?
And when would the GC remove obj1
from memory if the later is true?
It depends on the type. There are Value Types and Reference Types.
Value types store the value itself in memory and each time you pass it around you're just copying the value (thusly, value type) unless you use something like public void Test(ref int x)
. The fact that ref is there means to pass the integer, by reference.
When you have a variable of a reference type (object) you're basically just holding onto a pointer. So it would pass off the same reference of the object.
You can confirm this by extending your code to do something like this:
obj2.ID = 3;
Console.WriteLine(obj1.ID); // => 3
obj1 (or the object itself since obj1 is just a reference) will be GC'd when there are no longer any references to the object.
If SomeObject dereives from ValueType, then the instance which lives in GetObject's scope will be destroyed as soon as it returns and a new instance will be created and assigned to obj2. If SomeObject is not a ValueType, aka reference type, then only it's reference will be returned, so you end up with 1 instance. It is not possible to predict when GC will destroy an object, however, GC only destroys reference types, ValueTypes are destroyed automatically when code execution runs out of it's scope.
Will obj2 simply be a reference in memory to obj1
Yes (assuming it's not a value type)
However one thing to note: objects are always passed by value in parameters, so if you alter GetObject:
public class SomeObject
{
public string Name { get; set; }
public int ID { get; set; }
public SomeObject() { ID = 1; Name = "test"; }
}
static void Main(string[] args)
{
SomeObject obj1 = new SomeObject();
GetObject(obj1, 2);
Console.WriteLine(obj1.ID); // prints 1
Console.Read();
}
public static void GetObject(SomeObject obj1, int id)
{
var obj = new SomeObject();
obj.ID = id;
obj.Name = "";
obj1 = obj;
}
Assuming that SomeObject
is a class, the method will return a reference to the object instance that it creates.
The object instance will not be copied, there is only one instance. In .NET there is no object copying going on unless you specifically ask for a copy to be made, for example by calling the Clone
method.
When talking about reference types, it's important to remember the difference between object instances, references to instances, and variables that holds references. The variable obj1
holds a reference to the instance, and the variable is allocated in the stack frame for the method, so it goes away when you exit the method. The reference is returned from the method, but at that time the variable no longer exist.
It will be a reference in memory to obj1
, assuming that obj1
is a class
and not a struct
.
If some object is a reference type you are correct in that you would get a reference copy if SomeObject is a value type you would get a copy. The Garbage collector would clean up SomeObject at some point later when it decided it wanted to free memory. You can however force the GC hand by calling GC.collect
精彩评论