It is very important to understand the differences between value types and reference types. The core of the difference is that the value of the type expression.
Consider:
int x = 10; SomeClass y = new SomeClass();
Here, the x value is really 10 - bits for 10 end in the memory associated with the variable x .
The y value is a reference - a way to access a single object in memory.
The difference becomes very important when you use assignment, in particular with mutable reference types:
int x1 = 10; int x2 = x1; SomeClass y1 = new SomeClass(); SomeClass y2 = y1; y1.SomeProperty = "Fred"; Console.WriteLine(y2.SomeProperty);
In both cases, the value of the variable is copied in the assignment - therefore, the value of x2 is 10; The value y2 is a reference to the same object. Therefore, when the data of an object is changed using the property in the penultimate, you can still see this difference through y2 .
You rarely write z1.SomeProperty = ... when z1 is a value type variable, since most value types are immutable. (You cannot change the value of the data itself - you need to explicitly assign the new value to the variable.) If you did, however, you will not see any changes through the variables that were previously initialized using the z1 assignment because the value would be copied to that assignment.
I have an article on value types and reference types that goes into detail in all of this.
C # and .NET now have a unified type system, so even value types inherit from System.Object . This means that you can call all messages from Object by value type values. Sometimes this requires boxing (converting a value of type value to Object ), and sometimes not ... I won’t go into all the rules right now. It is important that if the value type overrides the method of the object (for example, ToString or GetHashCode ), you do not need to specify a value to call the method.
While boxing has a performance limit, it is usually overrated in my experience . These days with generics, boxing is really not needed as much as it was before, but as long as you use it only wisely, it is unlikely to become a serious performance problem in your application.
EDIT: Regarding games, performance, and learning things a little at a time ...
I have seen many people asking questions regarding a relatively advanced topic without understanding the basics. There is nothing wrong with being a beginner, obviously, but in my opinion, it is very important to first learn the basics, in an environment “friendly to beginners,” which I don’t think games are considered so.
Personally, I believe that console applications are the easiest way to learn most of the basic new concepts - be it language features, input / output files, collections, web services, streams, etc. Obviously, for things like “learning Windows Forms,” you can't do that with a console application — but it really helps if nothing but the Windows Forms part is new to you.
Therefore, I highly recommend that you learn the basics of C # - things like how value types and reference types work, how parameter passing, generics, classes, inheritance, etc. work. - before moving on to games. This may sound like extra work, but it will most likely save you time later. When something doesn't behave as you expect, you will know how the language works, so you can focus on the API in different ways, etc. Trying to learn one thing at a time makes the whole process smoother, in my experience.
In particular, performance requirements for games mean that sometimes it's worth writing very non-idiomatic C #. Things like pre-distributing objects and reusing them where you usually created new objects ... even creating volatile structures that I would almost never do in normal development. In a critical game cycle, boxing or creating any objects in general may be a bad idea - but this does not mean that these things are “expensive” in a normal coordinate system. It is really important that you understand when these things are suitable, and when they are not ... and if you start developing games, you will get an unbalanced view of these things, IMO. You can also try to optimize micro-areas where you really don't need it - but if you have solid grounding in C # and .NET for starters, you'll be in a better position to get everything in perspective.