4 Ways To Send Parameters To A C# Method

Posted by Ahmed Tarek Hasan on 9/04/2012 09:52:00 PM with 5 comments
Actually, the way a parameter can be sent to a method depends on two factors:
  • Type of object/variable to be sent to the method
    • Value type
    • Reference type
  • Way of sending the parameter
    • By value
    • By reference

So, just by guessing, we can say that we have 4 ways to send a parameter to a method. These 4 ways are:
  1. Sending "Value Type", "By Value" ............................... Val By Val
  2. Sending "Value Type", "By Reference" ........................ Val By Ref
  3. Sending "Reference Type", "By Value" ........................ Ref By Val
  4. Sending "Reference Type", "By Reference" ................. Ref By Ref
Some developers mistakenly consider the last two as one ..... hang on and you will know the difference between them.


First, let's point out some important points:
  • We have two types of memories; stack and heap
  • Value types are fully stored in the stack
  • Reference types are partially stored between the stack and heap as follows:
    • A location is reserved in the heap containing the actual value types contained by the reference type
    • A location is reserved in the stack containing the address of the location stated above (in the heap)
  • When sending parameter to a method "By Val", we just send a copy of the actual parameter, not the same parameter instance
  •  When sending parameter to a method "By Ref", we send the same instance of the parameter, not a duplicate copy
  • Applying changes to reference type members differs from applying changes to the reference itself

Second, lets discuss each of the 4 ways;


Val By Val:
This means we are sending a value type by value. In other words, we are sending a copy of a value type (lets say int).

4 Ways To Send Parameters To A C# Method

Since we are sending a copy, then we will copy the value inside the stack location (x) to another location (x') to be eventually used in the call. So, any changes applied inside the method will be applied to this copy (x') and the source value (x) will not be affected at all.

int x = 1;
increment(x);

public void increment(int num)
{
        num++;
}

Value of x will still be equal to 1 because any changes applied inside the method "increment" is applied to a copy of x (x') not x itself


Val By Ref:
This means we are sending a value type by reference. In other words, we are sending the exact value type (lets say int) instance.

4 Ways To Send Parameters To A C# Method
Since we are sending the same exact instance, then the value to be sent to the method will be x and all changes applied inside the method will be applied on x.

int x = 1;
increment(ref x);

public void increment(ref int num)
{
        num++;
}

Value of x will be equal to 2 because any changes applied inside the method "increment" is applied to x itself.


Ref By Val:
This means we are sending a reference type by value. In other words, we are sending a copy of the reference type (lets say employee class).

4 Ways To Send Parameters To A C# Method
Since we are sending a copy, then we will copy the value inside the stack location (x) to another location (x') to be eventually used in the call. So, we will copy the address 1 to a new location in the stack (x'). This means that the new stack location x' will be referencing the same location in the heap as x (because both x and x' hold the same heap location address). So, applying changes on the reference type members (properties like employee name, age, ....) will reflect in the source reference type instance. BUT, applying changes on the reference itself will change the link (address) of x' which makes it point to another heap location leaving the original location as it is.

Employee x = new Employee();
x.Name = "Ahmed";
Rename(x);

public void Rename(Employee emp)
{
        emp.Name = "Tarek";
}

x.Name will be equal to "Tarek" because both x and x' are pointing at the same heap location address sharing the same employee members (Name, Age, .....). So, any changes in x' members reflect in x members.

BUT

Employee x = new Employee();
x.Name = "Ahmed";
Rename(x);

public void Rename(Employee emp)
{
        emp = null;
}

x will not be equal to null and x.Name will be equal to "Ahmed". Why????? because when we set emp = null inside the method, we changed the reference (address) to which the x' is pointing so that at this point x' is pointing to a different heap location than that of x and we can deal with x and x' as two totally different references. So, when x' is set to null, it broke its reference to the heap location but x is still reserving the same reference to the heap location, this means that x is not null.


Ref By Ref:
This means we are sending a reference type by reference. In other words, we are sending the exact reference type (lets say employee class) instance.

4 Ways To Send Parameters To A C# Method

Since we are sending the same exact instance, then we will be sending x to the method and any changes applied to the reference members or the reference itself inside the method will be applied to the reference.

Employee x = new Employee();
x.Name = "Ahmed";
Rename(ref x);

public void Rename(ref Employee emp)
{
        emp.Name = "Tarek";
}

x.Name will be equal to "Tarek" because both x and x' are pointing at the same heap location address sharing the same employee members (Name, Age, .....). So, any changes in x' members reflect in x members.

ALSO

Employee x = new Employee();
x.Name = "Ahmed";
Rename(ref x);

public void Rename(ref Employee emp)
{
        emp = null;
}

x will be equal to null because setting x'=null is totally equivalent to x=null


I wish this cleared up the whole thing for you.
Good Luck :)




Categories: ,