Skip to main content

c# reference types passed by value or reference


Download

Time and again I have heard that in C#, method arguments are passed based upon there type. i.e. Value types are passed by value and reference types are passed by reference. This is so untrue. Reference types have nothing to do with pass by value.

Let us talk some basic. Consider the assignment first. When you assign a value type to another its value is copied. This is because value type variable contains its data directly. When you assign a reference type variable to another only the reference gets copied. This is because a reference type variable does not contains its data directly. It only holds reference to data.

Thus, when we pass a value type, its value gets copied and when we pass a reference type its reference gets copied. That is why if we change the value of a value type variable in the block (method), the change is not seen outside of it. On the other hand if we change the value of member of reference passed to the block from within the block the change persists outside the block.

Ok ! OK!

Some of you may say that, that is why reference types are passed by reference.

Wait! Wait!

Try changing the reference itself. You won't be able to do that. So actually you changed the value on the heap which was being pointed by the reference variable but you were not able to change the variable. Now, try using out or ref keywords and create a new reference type variable from within the block. You will succeed.

Actually when we are passing reference type without using out or ref we are passing just a pointer and that is why if we are trying to use new (to create a new object) we were not able to do that. On the other hand when we passed them using out or ref we passed pointer to pointer and that is why we were able to change the pointer being pointed using the new keyword.

Thus, we can safely say that in each case we changed the value being pointed by the reference and were not able to change the argument.


using System;
using System.Threading;

namespace ArgumentsPassByValue
{
    class Program
    {
        static void Main(string[] args)
        {
            Worker worker = new Worker();
            Request request = new Request();
            request.Id = 4;

            Console.WriteLine(request.Id + " : " + request.GetHashCode());

            worker.PassByReference(ref request);
            Console.WriteLine(request.Id + " : " + request.GetHashCode());

            //first request object will be collected as it is not being used
            GC.Collect();

            //forced thred to sleep so that you can see that first object has been 
            //collected and still we are using the variable request because it is pointing to some other location now.
            Thread.Sleep(1000);

            Console.WriteLine(request.Id + " : " + request.GetHashCode());
            Console.ReadLine();
        }
    }

    internal class Request
    {   
        public int Id { get; set; }

        ~Request()
        {
            Console.WriteLine(this.GetHashCode() + " : I am dying");
        }
    }

    internal class Worker
    {
        public void PassByReference(ref Request request)
        {
            request = new Request();
            request.Id = 6;
        }
        public void ValueChanger(Request request)
        {
            Console.WriteLine(request.Id + " : " + request.GetHashCode());
            request = new Request();
            request.Id = 6;
        }
    }
}

Some more references : http://msdn.microsoft.com/en-us/library/s6938f28.aspx

Comments

Popular posts from this blog

Create a background / taskbar application in c# .NET

Recently, I was working on integration of two windows applications. First application will launch the second application on login and then they both will communicate using pre-defined set of instructions. There were some complications (I am not going into them) and thus we decided to have a third application which actually will act as mediator. First application will launch the mediator (third application) and it will launch the second application. For this purpose we needed to create a task bar application (which will run in background). How To ·          Create a new windows project and delete the default form (Form1). ·          In Program.cs create a new class and inherit it from Form. ·          Please refer the code below. ·          Now change the Main method. In Application.Run change the startup objec...

Check SQL Server Job status (State) using sp_help_job and xp_sqlagent_enum_jobs

This article is about checking the status of a SQL job. In our work place we have lot of SQL jobs. These jobs will run whole day and are business critical. They will load the data and generate extracts which will be used by business people. Thus, it becomes quite essential to support the system efficiently so that the job finishes in time and as desired. Also, while designing a new system sometimes we need to check the dependency of one job over another. In such scenario we need to check whether a particular job has finished or not. All this can be achieved in SQL Server by using the procedures:- sp_help_job xp_sqlagent_enum_jobs Note: xp_sqlagent_enum_jobs is an undocumented proc inside of sp_help_job and is used extensively to get SQL agent job information. sp_help_job: This procedure gives some insight into the status, and information, about a job. This stored procedure provides information such as last start time, job status etc. Syntax sp_help_job { [ @job_id= ] jo...

Java 8 JMX Default Metrics

This is more of a note. Here you can find default types and attributes for JMX on top of Java 8. Code: I will clean and explain it later :( private static void WriteAttributes(final MBeanServer mBeanServer, final ObjectName http) throws InstanceNotFoundException, IntrospectionException, ReflectionException { MBeanInfo info = mBeanServer.getMBeanInfo(http); MBeanAttributeInfo[] attrInfo = info.getAttributes(); System.out.println("Attributes for object: " + http +":\n"); for (MBeanAttributeInfo attr : attrInfo) { System.out.println(" " + attr.getName() + "\n"); } } Attributes for object: java.lang:type=MemoryPool,name=Metaspace:   Name   Type   Valid   Usage   PeakUsage   MemoryManagerNames   UsageThreshold   UsageThresholdExceeded   UsageThresholdCount   UsageThresholdSupported   CollectionUsageThreshold   Collectio...