C# (or .NET): Primitive Types, Value Types, Reference Types and System.ValueType.
I think this is one of the most important topics in .NET, but it is interesting to see what kind of misunderstandings are out there. Even with programmers who have used .NET for years.
DISCLAIMER 1:
The goal of this blog entry is not to give another in depth, all-encompasing overview - but rather a summary of the conversations I've had with people and a summary of some confusing MSDN documentation. Also I won't address the issue of what to use when and the wonderful side effects (which is indeed very important to understand but I'll leave it for another time). There are really good articles out there that do a way better job than I could anyway. Click here for one of them.
But let's get back to business here...
In the following I will refer to one MSDN article as MSDN. You can find it here.
DEFINITIONS (based on MSDN):
Primitive Types:
MSDN: Any data types directly supported by the compiler are called primitive types
TOM: e.g. int->System.Int32, long -> System.Int64
Complete List of Types: http://msdn.microsoft.com/en-us/magazine/bb984984.aspx
Value Types:
MSDN (on top of the page): A type declared using struct is a Value Type
Reference Types:
Types declared using class are reference types.
Hence:
RESULT 1: A primitive Type is not the same then a Value Type! (I don't know how often I heart people saying that they are. Including me in the past :-)
QUESTION 1: What about Enum? Aren't they Value Types too?
QUESTION 2: How do we test for Value Types?
ANSWER 1: The MSDN article gives a well known answer a little bit later:
Value types are implicitly derived from System.ValueType !
QUESTION 3: Are structs derived from System.ValueType too? I thought they are "the" Value Type by Definition?
Before we answer question 3, let's answer question 2 and use it as a springboard to answer this.
ANSWER 2:
Test for Value Type (according to ANSWER 1). Click here for details.
if (x is ValueType) { //yep x is a Value Type }
Now let's use answer 2 to answer question 3:
(I hope you are totally confused about all the questions and answers by now :-)
public struct TomStruct
{
public string First { get; set; }
public string Last { get; set; }
public override string ToString()
{
return First + ", " +Last;
}
}
TomStruct p1 = new TomStruct() { First = "Tom", Last = "Fischer" };
if (p1 is System.ValueType)
{
Console.WriteLine("TomStruct derives from System.ValueType");
}
And as we suspeceted the output verifies that struct (or Enum) derives from ValueType!
So let's try a new Tom Definition for ValueTypes:
DEFENTIION for Value Types:
Every type, deriving from System.ValueType is a Value Types. This includes types defined via struct or enum .
(I bet now I forgot a type here:-) But at least this Defintion does not exclude it :-) You gotta love logic!
I hope you had some fun with me here. Sometimes the most basic stuff is the easiest to get confused about :-)
Looking forward to reading lots of comments,
Tom