C# / .NETDevOpsMisc
C# / .NET
Value types, reference types and practical uses
Alexandru Puiu
Alexandru Puiu
June 13, 2013
1 min

Table Of Contents

Looping over a list:
Method calls:

C# has two different types of variables: value types and reference types. While in C and C++ primitive types can contain values or references and certain complex types (arrays, objects) can only be used via reference, in C# the line between the two types is very clear. Numeric types(int, decimal, double, etc.), bool and structs access the values directly. Class, object, interface, delegate string and dynamic are only accessed and used via reference. Because of all the awkwardness with referencing and dereferencing in C and C++, C# uses the ‘ref’ keyword only for those cases where you want to modify a value type outside of your current scope.

If you’ve worked with C# a bit you’re probably used to always working with copies in any situation outside of simple assignment (=). If you loop over a collection, inside the loop you’re working with copies. If you pass something to a function, that something is a copy. However the difference between value types and reference types often means a copy isn’t always a copy. Knowing when this is not the case can help you spot troublesome bugs, and easily solve problems that might have taken you much longer. Here are a few example cases:

Example class:

class MyClass
    public int Value;
    public MyClass(int value) { this.Value = value; }
    public static void Increment1(int i) { i++; }
    public static void Increment2(ref int i) { i++; }
    public static void Increment3(MyClass o) { o.Value++; }


int i = 9;
int j = i; //j stores a copy of the value of i
var myObject = new MyClass(9);
var myObject2 = myobject; // myObject2 stores a copy of the reference to myObject so 
                          // any modifications to myObject2 will be reflected in 
                          // myObject as well

Looping over a list:

List myList = new List{1, 2, 3};
List myObjectList = new List { new MyClass(1), new MyClass(2), new MyClass(3) };

foreach(var i in myList)
    i++; //doesn't change anything in the original list since i is a copy

foreach(var o in myObjectList)
    o.Value++; // o is a copy of the reference to each o object, so any operations on
               // its interior values change the original object

foreach(var o in myObjectList)
    o = new MyClass(o.Value++); // doesn't change anything since you're assigning a 
                                // new reference to a variable that contains a copy 
                                // of the reference to the original object

Method calls:

int i = 9;
var o = new MyClass(9);

MyClass.Increment1(i); // does nothing since it's working on a copy of i
MyClass.Increment2(ref i); // works since i is passed by reference
MyClass.Increment3(o); // works since a copy of the reference to o is passed so any
                       // work on o'smembers changes the location in memory o refers
                       // to, not o itself


Alexandru Puiu

Alexandru Puiu

Engineer / Security Architect

Systems Engineering advocate, Software Engineer, Security Architect / Researcher, SQL/NoSQL DBA, and Certified Scrum Master with a passion for Distributed Systems, AI and IoT..



Social Media


Related Posts

RavenDB Integration Testing
Using RavenDB in Integration Testing
December 24, 2022
2 min

Subscribe To My Newsletter

I'll only send worthwhile content I think you'll want, less than once a month, and promise to never spam or sell your information!
© 2023, All Rights Reserved.

Quick Links

Get In TouchAbout Me

Social Media