Question

I am reading following blog by Eric Lippert: The truth about Value types

In this, he mentions there are 3 kinds of values in the opening:

  1. Instance of Value types

  2. Instance of Reference types

  3. References

    It is incomplete. What about references? References are neither value types nor instances of reference types, but they are values..

So, in the following example:

int i = 10;
string s = "Hello"

First is instance of value type and second is instance of reference type. So, what is the third type, References and how do we obtain that?

Was it helpful?

Solution

So, what is the third type, References and how do we obtain that?

The variable s is a variable which holds the value of the reference. This value is a reference to a string (with a value of "Hello") in memory.

To make this more clear, say you have:

 string s1 = "Hello";
 string s2 = s1;

In this case, s1 and s2 are both variables that are each a reference to the same reference type instance (the string). There is only a single actual string instance (the reference type) involved here, but there are two references to that instance.

OTHER TIPS

Fields and variables of reference type, such as your s, are references to an instance of a reference type that lives on the heap.

You never use an instance of a reference type directly; instead, you use it through a reference.

A reference is not really a 'third type'. It's actually a pointer that refers to a concrete instance of an object. Take a look at this example:

class MyClass
{
    public string Str { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        int a = 1;
        int b = 2;
        int c = 3;
        var myObj = new MyClass
        {
            Str = "Whatever"
        };

        Console.WriteLine("{0};\t{1};\t{2};\t{3}", a, b, c, myObj.Str);
        MyFunction(a, ref b, out c, myObj);
        Console.WriteLine("{0};\t{1};\t{2};\t{3}", a, b, c, myObj.Str);

        Console.ReadLine();
    }

    static void MyFunction(int justValue, ref int refInt, out int outInt, MyClass obj)
    {
        obj.Str = "Hello";
        justValue = 101;
        refInt = 102;
        outInt = 103; // similar to refInt, but you MUST set the value of the parameter if it's uses 'out' keyword
    }
}

The output of this program is:

1;      2;      3;      Whatever
1;      102;    103;    Hello

Focus on the MyFunction:

The first parameter we pass is a simple int which is a value type. By default value types are cloned when passed as the parameter (a new instance is being created). That's why the value of 'a' didn't change.

You can change this behavior by adding 'ref' or 'out' keyword to the parameter. In this case you actually pass a reference to that very instance of your int. In MyFunction the value of that instance is being overridden. Here you can read move out ref and out

The last example is the object of MyClass. All classes are reference types and that's why you always pass them as references (no special keywords needed).

You can think about a reference as about an address in computer memory. Bytes at that address compose your object. If you pass it as value, you take that bytes out and pass them to a function. If you pass it as a reference you only pass the address. Than in your called function you can read bytes from that address or write to that address. Every change affects the calling function variables, because they point to exactly the same bytes in computer memory. It's not exactly what happens in .Net (it runs in a virtual machine), but I think this analogy will help you understand the concept.

Why do we use references? There are many reasons. One of them is that passing a big object by value would be very slow and would require cloning it. When you pass a reference to an object, than no matter how big that object is you only pass w few bytes that contain it's 'address' in memory.

Moreover your object may contain elements that cannot be cloned (like an open socket). Using reference you can easily pass such an object between functions.

It's also worth mentioning that sctructs, even though they look very similar to classes are actually value types and behave as value types (when you pass a struct to a function, you actually pass a clone - a new instance).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top