Click here to Skip to main content
12,622,568 members (33,249 online)
Click here to Skip to main content
Add your own
alternative version

Stats

202.2K views
889 downloads
57 bookmarked
Posted

Ref and Out (The Inside Story)

, 13 Oct 2015 CPOL
Rate this:
Please Sign up or sign in to vote.
My efforts in this article will be to make this understanding simpler and focus on the internal logic of ref and out.

Introduction

One might incorporate n number of methods to return or pass parameters while method calling. Most of the time a developer tries to escape using C# features of parameter passing by reference. Had he/she known the power of ref and out, a developer would certainly make full use of this feature of parameter passing. My efforts in this article will be to make this understanding simpler and focus on the internal logic of ref and out.

Value Types vs Reference Types(Quick Overview)

As we know that in C# there are two type of "types": reference types and value types. Since they act in their own special way they must always be used according to the real need and not by force.

Reference type variables have their value a reference to the appropriate data rather than the data itself. Its ByRef in VB6,& in C++.

Value type directly contain the data and not the reference. And when assigned, the copy of that data is made to the assingment. To elaborate, a new storage space is created for the variable in the function member declaration, and it starts off with the value that we specify in the member method calling. If we change that value, it doesn't affect any variable involved in that call.

Why Pass by Reference?

While writing a code, we often come across situations where we need to return multiple values from a single function/method. But a method can only return a single value.The question is how do we overcome such situation.Answer is simple, use reference types, but how?

Let's throw some light on when to use the methodology . When you pass in a variable to a method, the value of that variable gets copied to the method by default. For values types, it means that the object itself gets copied on the other end for reference types, it means that only the thing that points at the object gets copied.

It is one way to save performance, else as larger as the reference type would be as more performance it would cost. So we can also refer this as "Call by Sharing". In a call by reference situation, if the variable of a reference type is changed inside the method, the caller variable also gets affected. If we change a the value of a value type, when passed to a method, it will never affect the caller variable.

Our Target (Ref and Out)

Parameters are always passed by value to a method by default.If we want to pass them by reference then we can use either out or ref keyword.

Reference parameters basically never pass the value of a variable used in the method calling, instead they use the variable themselves. Rather than creating a new storage for that variable in the method declaration, the very same storage space is used, so the value of the variable in the member method and the value of the reference parameter will always be the same. Reference parameters require ref modifier as part of both the declaration and the calling.

Output parameters are very much like reference parameters. The variable specified at the time of calling doesn't need to have been assigned a value before it is passed to the called method. When the method is invoked completely we can read that variable as it is assigned by now.

Like reference parameters, output parameters don't create a new storage location, but use the storage location of the variable specified on the invocation. Output parameters need the out modifier as part of both the declaration and the invocation - that means it's always clear when you're passing something as an output parameter.

Reference : http://www.yoda.arachsys.com/csharp/parameters.html

Consider the Following Scenario

I have developed a simple console application to clarify the logic with the following code in Program.cs class,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ref_and_out
{
    class Program
    {
        static void Main(string[] args)
        {
            string name1 = "Akhil";
            string name2="Akhil";
            Program program=new Program();
            Console.WriteLine("Name Before Calling RefMethod : "+ name1);
            program.RefMethod(ref name1);
            Console.WriteLine("Name After Calling RefMethod : " + name1);
            Console.WriteLine("Name Before Calling OutMethod : " + name2);
            program.OutMethod(out name2);
            Console.WriteLine("Name After Calling OutMethod : " + name2);
            Console.ReadLine();
        }
        private void RefMethod(ref string nameRef)
        {
            nameRef = "Akhil Mittal";
        }
        private void OutMethod(out string nameOut)
        {
            Console.WriteLine(nameOut);
        }
    }
}

As we can see in the above easy to understand code, I have created two methods RefMethod and OutMethod to handle passed parameters into their invocation, and to check the values of my variables before and after assignment. When I compiled the code I got the following compile time error:

Certainly the error helped me to discover some new facts about out and ref:

  • The parameter initially is considered not assigned in case of out.
  • The variable specified at the time of calling doesn't need to have been assigned a value before it is passed to the function member. It's the responsibility of the called method to assign it before completing the execution so that we can read it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ref_and_out
{
    class Program
    {
        static void Main(string[] args)
        {
            string name1 = "Akhil";
            string name2;
            Program program=new Program();
            Console.WriteLine("Name Before Calling RefMethod : "+ name1);
            program.RefMethod(ref name1);
            Console.WriteLine("Name After Calling RefMethod : " + name1);
            program.OutMethod(out name2);
            Console.WriteLine("Name After Calling OutMethod : " + name2);
            Console.ReadLine();
        }
 
        private void RefMethod(ref string nameRef)
        {
            nameRef = "Akhil Mittal";
        }
 
        private void OutMethod(out string nameOut)
        {
            nameOut = "Akhil Mittal in out method";
        }
    }
}

And as expected, it worked fine.

Then I check to see if this is also the same with ref. And again, I make some modifications:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ref_and_out
{
    class Program
    {
        static void Main(string[] args)
        {
            string name1;
            string name2;
            Program program=new Program();
            Console.WriteLine("Name Before Calling RefMethod : "+ name1);
            program.RefMethod(ref name1);
            Console.WriteLine("Name After Calling RefMethod : " + name1);
            program.OutMethod(out name2);
            Console.WriteLine("Name After Calling OutMethod : " + name2);
            Console.ReadLine();
        }
        private void RefMethod(ref string nameRef)
        {
            nameRef = "Akhil Mittal";
        }
        private void OutMethod(out string nameOut)
        {
            nameOut = "Akhil Mittal in out method";
        }
    }
}

And yes, I got the compile time error.

That means unlike out type, in ref:

  • Parameter must be initialized before calling the function.

Therefore Out and ref basically add something new to the the meaning of "pass by reference" by specifying that the variable must be initialized and will be modified (ref) and that the same will be initialized inside of the function (out).

The Inside Story (Some Points to Remember)

  • Several inbuilt methods as "TryParse" (one of my favourite) use out and not ref as the inside the internal implementation the library mainly uses ref. Therefore out is a special form of ref in which the referenced memory should not be initialized before the call.
  • Both the method definition and the calling method must explicitly use the ref / out keyword.
  • There is no "boxing" when a value type is passed by reference.
  • Properties cannot be passed via out or ref, as properties are actually methods.
  • ref / out are not considered to be a part of method signature at compile time, so methods cannot be overloaded, if the only difference between them is that one of the methods takes a ref argument and the other takes an out argument.

And so the final (running) code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ref_and_out
{
    class Program
    {
        static void Main(string[] args)
        {
            string name1="Akhil";
            string name2;
            Program program=new Program();
            Console.WriteLine("Name Before Calling RefMethod : "+ name1);
            program.RefMethod(ref name1);
            Console.WriteLine("Name After Calling RefMethod : " + name1);
            program.OutMethod(out name2);
            Console.WriteLine("Name After Calling OutMethod : " + name2);
            Console.ReadLine();
        }
        private void RefMethod(ref string nameRef)
        {
            nameRef = "Akhil Mittal";
        }
        private void OutMethod(out string nameOut)
        {
            nameOut = "Akhil Mittal";
        }
    }
}

And the output:

Following is one good read written by Mr. @Shivprasad-koirala  . He explains the concept in asimpler and concise way. http://www.codeproject.com/Articles/1033981/Out-and-REF-in-Csharp

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Akhil Mittal
Architect Magic Software Inc.
India India
I am a Microsoft MVP, C# Corner MVP,a Code project MVP,blogger,programmer by heart and currently working as a Sr. Analyst in Magic Software and have an experience of more than 8 years in C#.Net. I am a B.Tech in Computer Science and hold a diploma in Information Security and Application Development. My work experience includes Development of Enterprise Applications using C#,.Net and Sql Server,Analysis as well as Research and Development. I am a MCP in Web Applications(MCTS-70-528,MCTS-70-515) and .Net Framework 2.0 (MCTS-70-536). Visit my personal blog CodeTeddy for more informative articles.
____________________________________________________________________________________________________
Article of Day http://www.asp.net/community/articles on 04 April 2016.
Article of Day http://www.asp.net/community/articles on 26 March 2016.
Article of Day http://www.asp.net/community/articles on 29 Jan 2016.
Article of Day http://www.asp.net/community/articles on 01 Aug 2015.
Article of Day http://www.asp.net/community/articles on 28 July 2015.
Article of Day http://www.asp.net/community/articles on 28 June 2015.
Article of Day http://www.asp.net/community/articles on 08 June 2015.
Article of Day http://www.asp.net/community/articles on 02 June 2015.
Article of Day http://www.asp.net/community/articles on 01 June 2015.
Article of Day http://www.asp.net/community/articles on 19 July 2014.
Article of Day http://www.asp.net/community/articles on 21 May 2014.
Article of Day http://www.asp.net/community/articles on 29 Oct 2013.
Article of Day http://www.asp.net/community/articles on 29 Sept 2013.
Article of Day http://www.asp.net/community/articles on 08 Sept 2013.
Article of Day http://www.asp.net/community/articles on 28 Aug 2013.
Article of Day http://www.asp.net/community/articles on 16 Aug 2013.
Winner http://www.c-sharpcorner.com/News/3067/july-2013-month-winners-announc
Group type: Collaborative Group

455 members


You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 4 Pin
Member 432084418-Oct-15 10:28
memberMember 432084418-Oct-15 10:28 
GeneralRe: My vote of 4 Pin
Akhil Mittal 18-Oct-15 18:33
mvp Akhil Mittal 18-Oct-15 18:33 
GeneralRe: My vote of 4 Pin
Akhil Mittal 20-Oct-15 5:11
mvp Akhil Mittal 20-Oct-15 5:11 
GeneralMy vote of 4 Pin
Nelson Costa Inácio14-Oct-15 0:37
memberNelson Costa Inácio14-Oct-15 0:37 
GeneralRe: My vote of 4 Pin
Akhil Mittal 14-Oct-15 7:05
mvp Akhil Mittal 14-Oct-15 7:05 
GeneralMy vote of 5 Pin
RapidGeek12-Aug-15 8:56
professionalRapidGeek12-Aug-15 8:56 
GeneralRe: My vote of 5 Pin
Akhil Mittal 14-Oct-15 7:05
mvp Akhil Mittal 14-Oct-15 7:05 
GeneralNice Work Pin
Dharmesh .S. Patil10-Jul-15 1:02
professionalDharmesh .S. Patil10-Jul-15 1:02 
GeneralRe: Nice Work Pin
Akhil Mittal 10-Jul-15 1:04
mvp Akhil Mittal 10-Jul-15 1:04 
GeneralRe: Nice Work Pin
Akhil Mittal 10-Jul-15 1:05
mvp Akhil Mittal 10-Jul-15 1:05 
QuestionMy Vote of 4 Pin
vidhi sarkar24-Mar-15 20:31
membervidhi sarkar24-Mar-15 20:31 
AnswerRe: My Vote of 4 Pin
Akhil Mittal 24-Mar-15 20:37
mvp Akhil Mittal 24-Mar-15 20:37 
GeneralMy vote of 5 Pin
Santosh K. Tripathi24-Mar-15 7:55
professionalSantosh K. Tripathi24-Mar-15 7:55 
GeneralRe: My vote of 5 Pin
Akhil Mittal 24-Mar-15 19:22
mvp Akhil Mittal 24-Mar-15 19:22 
GeneralMy vote of 2 Pin
rutav21-Mar-14 0:53
memberrutav21-Mar-14 0:53 
GeneralRe: My vote of 2 Pin
Akhil_Mittal9-May-14 8:24
mvpAkhil_Mittal9-May-14 8:24 
Generalgood Pin
Harikrishnanvr11-Mar-14 2:01
memberHarikrishnanvr11-Mar-14 2:01 
GeneralRe: good Pin
Akhil_Mittal11-Mar-14 2:27
mvpAkhil_Mittal11-Mar-14 2:27 
GeneralMy vote of 5 Pin
gupta_pankaj_magic14-Aug-13 7:55
membergupta_pankaj_magic14-Aug-13 7:55 
SuggestionOne tiny correction. Pin
sarkoff26-Feb-13 4:00
membersarkoff26-Feb-13 4:00 
GeneralRe: One tiny correction. Pin
Akhil_Mittal20-Jul-13 6:39
groupAkhil_Mittal20-Jul-13 6:39 
GeneralMy vote of 3 Pin
AnupamRobinson24-Feb-13 23:17
memberAnupamRobinson24-Feb-13 23:17 
GeneralRe: My vote of 3 Pin
Akhil_Mittal25-Feb-13 1:30
memberAkhil_Mittal25-Feb-13 1:30 
GeneralMy vote of 5 Pin
Da. Mann24-Feb-13 22:44
memberDa. Mann24-Feb-13 22:44 
GeneralRe: My vote of 5 Pin
Akhil_Mittal24-Feb-13 23:01
memberAkhil_Mittal24-Feb-13 23:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.161128.1 | Last Updated 14 Oct 2015
Article Copyright 2013 by Akhil Mittal
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid