ASP.NET: Reference type as parameter to a method


Introduction :

This post is about passing reference type (like array) to a method. Whatever I have written below is purely based on my experiments and the knowledge I gained from MSDN etc. So, if somebody reading this post has a better idea then please comment.  Before I write something, let quickly look at the following 3 snippets of code. For a quick demo I have used Console Application but, the concept below holds good for either ASP.Net or Windows Application or any other. As C# is the most advanced and mostly used programming language, I have decided to use it for my demonstration.

Have a look at the code :

Snippet 1 :

//Demonstration with Integer parameter
static void Main(string[] args)
{
  int num = 1000;
  Console.WriteLine("Initial Value in num: {0}", num);
  Console.WriteLine("______________________________");
  PlusPlus(num);
  Console.WriteLine("______________________________");
  Console.WriteLine("Final Value in num: {0}", num);
  Console.ReadLine();
}

static void PlusPlus(int numFormal)
{
  numFormal += 1;
  Console.WriteLine("Value in numFormal: {0}", numFormal);
}

Output Of Snippet 1 :

Initial Value in num: 1000

_____________________

Value in numFormal: 1001

_____________________

Final Value in num: 1000

Snippet 2 :


//Demonstration with Array(Int) parameter
static void Main(string[]  args)
{
  int[] arrNum = { 1000, 2000, 3000 };
  for(int i=0;i  {
    Console.WriteLine("Initial Value in arrNum["+i+"] : {0}", arrNum[i]);
  }
  Console.WriteLine("_________________________________________");
  PlusPlus(arrNum);
  Console.WriteLine("_________________________________________");
  for (int i = 0; i < 3; i++)
  {
    Console.WriteLine("Final Value in arrNum["+i+"] : {0}", arrNum[i]);
  }
  Console.ReadLine();
}

static void PlusPlus(int[] arrNumFormal)
{
  for (int i = 0; i < 3; i++)
  {
    arrNumFormal[i] += 1;
    Console.WriteLine("Value in arrNumFormal["+i+"]: {0}", arrNumFormal[i]);
  }
}

Output Of Snippet 2 :

Initial Value in arrNum[0]: 1000
Initial Value in arrNum[1]: 2000
Initial Value in arrNum[2]: 3000
__________________________
Value in arrNumFormal[0]: 1001
Value in arrNumFormal[1]: 2001
Value in arrNumFormal[2]: 3001
__________________________
Final Value in arrNum[0]: 1001
Final Value in arrNum[1]: 2001
Final Value in arrNum[2]: 3001

Snippet 3 :


//Demonstration with string parameter
static void Main(string[] args)
{
  string str = "original string";
  Console.WriteLine("Initial Value in str: {0}", str);
  Console.WriteLine("______________________________");
  ChangeString(str);
  Console.WriteLine("______________________________");
  Console.WriteLine("Final Value in str: {0}", str);
  Console.ReadLine();
}

static void ChangeString(string strFormal)
{
  strFormal = "changed string";
  Console.WriteLine("Value in strFormal: {0}", strFormal);
}

Output Of Snippet 3 :

Initial Value in str: original string
__________________________
Value Of numFormal: changed string
__________________________
Final Value Of num: original string

Analysis :

Analysis of Snippet 1 & its result :

In the Snippet no. 1, I have declared a local integer variable ‘num’ and assigned a value 1000 to it. Then after displaying(“Initial Value in num: 1000”) it on the screen I called a method PlusPlus(), which takes a single argument of type int. To this method I passed the variable ‘num’. The body of the static method PlusPlus() consists of only 2 lines of code. First line increments the formal parameter by 1 and then the second line of code prints(“Value in numFormal: 1001”) it on the screen.Then again I am printing(“Final Value in num: 1000”) the value hold by the variable ‘num’.
Thing to notice here is after passing the variable to the method PlusPlus() and there although I am incrementing it by 1, it did not change its original value. This is because when I am passing a int variable to a method, exactly I am passing the value hold by the variable as int is a value type and the method computes on the value passed to it, which is hold by the formal parameter not the actual parameter.

Analysis of Snippet 2 & its result :

I have repeated the same process as in the Snippet 1 except I have changed the local variable integer to a integer array. But, here the result is something different. The difference is- the changes I have done to the formal parameter in the method PlusPlus()  also reflects for the actual parameter or, the original integer array declared in the main() method. This is happened as array is a reference type so, when I am passing an array to a method, actually I am passing its reference and now the formal parameter holds the same reference as the actual parameter. So, when I am changing the value present in any of the indices of the array in the formal parameter it reflects in the actual parameter also.

Analysis of Snipet 2 & its result :

Once again I have repeated the same process as snippet 1 and 2 with the same little change in the datatype of the variable. Now, I want to see the result when I am using a string variable, which is of reference type. But the result is same as the snippet 1 where I had used integer variable.

Now, Question is- why this deviation ?

This is happened because, although string is a reference type but the class System.String or, its alias string is immutable. If you want to know more on immutable type you can search it in MSDN. I will discuss about mutable and immutable type in details in my next blog post but for now, you can consider the real meaning of the English word ‘immutable’ – ‘Not susceptible to change’. It means we can not change the value hold by a string variable. When we are changing the value hold by the string variable in the method ChangeString(), actually a new variable is created to store the new value. So, the changes did not reflect on the actual parameter or, the original variable.

Conclusion :

When we are passing an array as parameter we should understand that, the calling method can change its value.

Advertisements

C Sharp: Under-utilized Padleft() method


What I am going to explain is not for a specific situation, we can use it in so many cases. I am talking about PadLeft() method of string class. To explain it, I am just showing you an example, which I found somebody doing while he is supposed to code for three dropdowns like Day,Month & Year. Following is the snippet of his code-

private void bindDay()
    {        
        ArrayList day = new ArrayList();
        for (var i = 1; i <= 31; i++)
        {
            if (i > 0 && i < 10)
            {
                var x = "0" + i;
                day.Add(x);
            }
            else
                day.Add(i);
        }
        ddlDays.DataSource = day;        
        ddlDays.DataBind();
}

Although this block of snippet may need improvements on some other line(s) of code but I am concentrating on the part inside the ‘for loop’. Yes, the if .. else .. block. Here, 5-7 lines of the code is intended to add days of date and with 2-digit format like 01,02,03..etc. I admit that there are so many ways to accomplish it, but I am just talking about the logic. In this code, it has a loop variable which checks the value to find if it is of single digit or two digits. Then if it is of 2-digits then no logic to go before adding it to the dropdownlist and if it is of 1-digit then it is to be padded with a ‘0’..This will work definitely fine for Day dropdown.

Now we can ask what happen when some body wants to form a dropdown with fixed no of 10 digits and a dumb answer will be -“Use 9-10 if..else conditions to do this”.

We can replace the whole if .. else .. by just using a simple method of System.String class – PadLeft(). Now after changing only the if else block with PadLeft(), the code will be like-

private void bindDay()
    {        
        ArrayList day = new ArrayList();
        for (var i = 1; i <= 31; i++)
        {
               day.Add(i.ToString().PadLeft(2,'0'));
        }
        ddlDays.DataSource = day;        
        ddlDays.DataBind();
} 

Here , PadLeft() is taking 2 parameters- width of the resulted string and the character to be padded to the left when string is of length less than 2.
This can also be used to scenarios where you need to generate a code (like Employee Code,Book Code, etc) of a fixed length.