Value types are the simpler of the two. Value types are often used to represent data itself. An integer, a Boolean or a point in 3D space are all examples of good value types.
Value types (structs) are declared by using the struct keyword. See the syntax section for an example of how to declare a new struct.
Generally speaking, We have 2 keywords that are used to declare value types:
Reference types are slightly more complex. Reference types are traditional objects in the sense of Object Oriented Programming. So, they support inheritance (and the benefits there of) and also support finalizers.
In C# generally we have this reference types:
New reference types (classes) are declared using the class keyword. For an example, see the syntax section for how to declare a new reference type.
The major differences between reference types and value types can be seen below.
This is the often mentioned difference between the two, but really, what it boils down to is that when you use a value type in C#, such as an int, the program will use that variable to refer directly to that value. If you say int mine = 0, then the variable mine refers directly to 0, which is efficient. However, reference types actually hold (as the name suggests) a reference to the underlying object, this is akin to pointers in other languages such as C++.
You might not notice the effects of this immediately, but the effects are there, are powerful and are subtle. See the example on changing reference types elsewhere for an example.
This difference is the primary reason for the following other differences, and is worth knowing.
When a value type is passed into a method as a parameter, if the method changes the value in any way, the value is not changed In contrast, passing a reference type into that same method and changing it will change the underlying object, so that other things that use that same object will have the newly changed object rather than their original value.
See the example of value types vs reference types in methods for more info.
What if I want to change them?Simply pass them into your method using the "ref" keyword, and you are then passing this object by reference. Meaning, it's the same object in memory. So modifications you make will be respected. See the example on passing by reference for an example.
Pretty much as it says, you can assign null to a reference type, meaning the variable you've assigned can have no actual object assigned to it. In the case of value types, however, this is not possible. You can, however, use Nullable, to allow your value type to be nullable, if this is a requirement, though if this is something you are considering, think strongly whether a class might not be the best approach here, if it is your own type.