Reputation: 63310
If one passes an object to a method using the 'Ref' keyword then what is the difference with passing it without the ref keyword?
Because both yield the same result, that the object has been altered when passing control back to the calling object.
Such as this:
class Student
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
class Program
{
static Student student = new Student();
static void Main( string[] args )
{
student.Age = 30;
student.Name = "StudentA";
Console.WriteLine("Original Student: {0}, Age: {1}", student.Name, student.Age);
SetStudent(ref student);
Console.WriteLine("Student by Ref {0}, Age{1}", student.Name, student.Age);
AnotherStudent(student);
Console.WriteLine("Just Another Student {0}, Age {1}", student.Name, student.Age);
Console.ReadLine();
}
public static void SetStudent( ref Student student )
{
student.Age = 16;
student.Name = "StudentY";
}
public static void AnotherStudent( Student studenta )
{
if (studenta.Equals(student))
{
Console.WriteLine("The same object in memory");
}
studenta.Age = 12;
studenta.Name = "StudentX";
}
}
When the student object is passed to AnotherStudent() it gets altered, event thought it is not passed by 'Ref'.
Can someone explain what is happening here?
EDIT
So what is the difference to passing a pointer to an object in C++ in a function?
Tony
Upvotes: 0
Views: 2341
Reputation: 50137
I am limiting the discussion to reference types (everything that is a class, meaning I am not talking about structs or built-in value types). For a full and more detailed discussion you can see this link here.
If you pass reference types without the ref keyword you are passing the reference by value, meaning that a copy of your reference will be made. At this point you can modify the object the ref is pointing to, BUT if you swap in another object (assigning to the ref object you passed in some other object you create) when the function returns the original object that lives outside the function that you passed in is still pointing to the same old reference.
If you pass reference types using the ref keyword instead you can swap in the object you passed in with something else because the reference is not merely being copied - the variable itself is being passed in flesh and bones to the function to do whatever, and you can even make it point to some other address in memory (instantiating another object and assigning it to your ref parameter).
As you point out, in both cases you will be able to modify your object. Basically passing by reference in C# corresponds to passing a simple pointer in C++, while passing without the ref keyword corresponds to passing a constant pointer in C++ (you can make changes but can't make it point to smt else).
Upvotes: 2
Reputation: 700850
Passing a variable by reference and passing a reference type is two different things. You can combine them by passing a reference type varaible by reference.
Passing a variable by reference simply means that the method can change the variable. The method gets access to the variable itself, not just a copy of the value. A variable doesn't have to be a reference type to be passed by reference. The few cases where passing by reference is used is actually mostly with value types.
When passing a reference type by reference, that means that the method gets access to the reference variable, not just a copy of the reference to the object. The method not only have access to the object, but it can also replace the reference in the variable with a reference to a different object.
Passing by reference is rarely needed, and certainly not something that you need to do just because you are passing a reference type as a parameter.
Upvotes: 1
Reputation: 4517
These examples illustrates the difference
methodA(ref object a)
{
a = new object();
}
methodB(object a)
{
a = new object();
}
object c = new object();
methodA(ref c); //now c points to an entire new object
methodB(c); // does not change the value of c
Upvotes: 0
Reputation: 26120
Try changing your two Student methods to:
public static void SetStudent( ref Student student )
{
student = new Student();
student.Age = 16;
student.Name = "StudentY";
}
public static void AnotherStudent( Student studenta )
{
studenta = new Student();
studenta.Age = 12;
studenta.Name = "StudentX";
}
The call to SetStudent
will now change your static student variable to reference a new instance because it is passed as a ref
. The call to AnotherStudent
won't change the reference.
Upvotes: 2
Reputation: 99824
Try reassigning the student object rather than setting properties of it.
public static void SetStudent( ref Student student )
{
student = new Student();
student.Age = 16;
student.Name = "StudentY";
}
public static void AnotherStudent( Student studenta )
{
studenta = new Student();
studenta.Age = 12;
studenta.Name = "StudentX";
}
Don't think of ref
as "passing by reference" because all reference types are passed by reference. Think of it as "reference to this object can be reassigned"
Upvotes: 3
Reputation: 1503869
Passing by reference allows the method to change the value of the argument passed to the method - so for a reference type, that allows it to change a variable's value to refer to a different object. Here's an example:
using System;
using System.Text;
class Test
{
static void PassByValue(StringBuilder x)
{
x.Append(" - Modified object in method");
x = new StringBuilder("New StringBuilder object");
}
static void PassByReference(ref StringBuilder x)
{
x.Append(" - Modified object in method");
x = new StringBuilder("New StringBuilder object");
}
static void Main()
{
StringBuilder builder = new StringBuilder("Original");
PassByValue(builder);
Console.WriteLine(builder);
builder = new StringBuilder("Original");
PassByReference(ref builder);
Console.WriteLine(builder);
}
}
In both cases, the original StringBuilder
has its contents modified, and then the parameter is assigned a new value. In the "pass by value" case, this doesn't change the value of the builder
variable in Main
. In the "pass by reference" case, the value of builder
refers to the new StringBuilder
, so the results are:
Original - Modified object in method
New StringBuilder object
In your case, you're not seeing any difference with or without ref
because you're not changing the value of the parameter itself - only the data in the object it refers to.
For more information, see my article on parameter passing.
Upvotes: 5
Reputation: 22859
The real difference will become apparent when you do this...
public static void SetStudent( ref Student student )
{
student = new Student { Age = 69, Name="Botox" };
}
...
var a = new Student()
var b = a;
SetStudent(ref a);
object.ReferenceEquals(a, b) // Should be false
Upvotes: 0
Reputation: 158399
When you pass an object to a method using the ref
key word, the called method can update the reference itself, not only the object. That means that in the following code snippet:
object a = new object();
SomeMethod(ref a);
...a
may be another object instance after the call than it was before the call. If you pass an object without the ref
keyword, the called method can update properties and members of the passed object, but cannot replace the object itself with another instance.
Upvotes: 0