Reputation: 31252
I'm a Java programmer. I have little knowledge on C#. But from the blogs I have read, Java supports only pass-by-value-of-reference whereas in C# the default is pass-by-value-of-reference but the programmer can use pass by reference if needed.
I have penned down my understanding of how a swap function works. I guess it is crucial to get this concept clear as it is very fundamental to programming concepts.
In C#:
public static void Main()
{
String ONE = "one"; //1
ChangeString(ONE); //2
Console.WriteLine(ONE); //3
String ONE = "ONE"; //4
ChangeString(ref ONE); //5
Console.WriteLine(ONE); //6
}
private static void ChangeString(String word)
{
word = "TWO";
}
private static void SeedCounter(ref String word)
{
word = "TWO";
}
Step 1: A string object with value one
is created on heap and the address of its location is returned stored in variable ONE
. Runtime Environment allocates a chunk of memory on the heap and returns a pointer to the start of this memory block. This variable ONE
is stored on the stack which is a reference pointer to the locate the actual object in memory
Step 2: Method changeString
is called. A copy of the pointer (or the memory address location) is assigned to the variable word. This variable is local to the method which means when the method call ends, it is removed from stack frame and is out of scope to be garbage collected.
Within the method call, the variable word is reassigned to point to a new location where TWO
object sits in memory. method returns
Step 3: Printing on the console should print ONE
, since what was changed in the previous step was only a local variable
Step 4: Variable one is reassigned to point to the memory location where object ONE
resides.
Step 5: method changeString
is called. This time reference to the ONE
is passed. what this means is the local method variable word is an alias to the variable one in the main scope. So, no copy of reference is done. Hence it is equivalent in thinking that the same variable one is passed to the method call. The method reassigns the variable to point to a different memory location which happens to hold TWO
. The method returns
Step 6: Now the variable one
on the outer scope i.e., in the main method is changed by method call and so it prints TWO
.
In Java
, step 5 is not possible. That is you cannot pass by reference
.
Please correct if the programming flow I described above is correct?
Articles I have read, here and here.
Upvotes: 6
Views: 612
Reputation: 20842
You seem to understand the semantics correctly. Just to draw some analogies in other languages..
In C#, the default is an object reference (one level of indirection) except with value types. Passing by reference is essentially passing a pointer to an object reference, which is double indirection.
The closest is a C or C++ analogy.
C++
void ChangeString(std::string word)
{
word = "TWO";
}
void SeedCounter(std::string &word)
{
word = "TWO";
}
C (Ignoring issues of const, etc.)
void ChangeString(char * word)
{
word = strdup("TWO");
}
void SeedCounter(char ** word)
{
*word = strdup("TWO");
}
But a Java analogy would probably have to be a class with a string member:
public class StringRef
{
public string val;
}
public static void ChangeString(string word)
{
word = "TWO";
}
public static void SeedCounter(StringRef strRefWord)
{
strRefWord.val = "TWO";
}
Elaborating per request.
In C# (or the CLR more specifically) a string variable is a pointer, but we refer to it as an object reference. The variable holds an address that points to a string object, usually somewhere on the heap. The variable itself is usually either a class field, where it likely exists on the heap, or a local variable or argument, so it exists on the stack or in a local variable slot (also on the stack). When you pass by reference, you are passing a pointer to your variable, not a pointer to the eventual object. Your "ref" param is A, A points to B which is your local variable or object field, and B points to C, the string object somewhere in memory. Passing by ref passes a A, which is a pointer to B, and you can now change B.
Upvotes: 3
Reputation: 203824
Your understandings of the semantics of passing by reference/value are correct.
Upvotes: 0