views:

873

answers:

2

I have been trying to understand the use of "primitives" in Java and C# and the difference between them (if any). I have asked a series of questions on SO and some of the answers seem to confuse the issue rather than clarify it. Some answers (and some MS documentation) appear to provide contradictory statements. From SO

and from MS: http://msdn.microsoft.com/en-us/library/ms228360%28VS.80,lightweight%29.aspx - "structs are very similar to classes" - "the Int32 class wraps the int data type" - "On the other hand, all primitive data types in C# are objects in the System namespace. For each data type, a short name, or alias, is provided. For instance, int is the short name for System.Int32".

My confusion lies largely with C# (I have programmed java for some while).

EDIT The following paragraph has been confirmed to be correct by @Jon Skeet

  • Java has two types (primitive and class). The words "value type" could be a synonym for primitive (although not widely used) and "reference type" for class. Java "wraps" primitives (int) in classes (Integer) and these classes have the complete power of any other class (can be null, used in collections, etc.)

EDIT @Jon has given a very clear statement on C# so I will delete my suggested truths and refer to his answer.

Further question: Is there a consensus on what the actual use of these terms should be? If there is a consensus I'd be very grateful for it spelt out explicitly. Otherwise I assume the terminology is muddled and therefore of limited use.

SUMMARY Thanks for very clear answers. There is a consensus (see accepted answer from @Jon) among those who really understand this and the MS docs are consistent (although they refer to Java in places and I misread these for C#)

+6  A: 

I haven't seen MS docs to be contradictory about this (MSDN is sometimes wrong, but on this specific issue, I've always seen it correct). The MSDN link you posted says:

For each primitive data type in Java, the core class library provides a wrapper class that represents it as a Java object. For example, the Int32 class wraps the int data type, and the Double class wraps the double data type.

On the other hand, all primitive data types in C# are objects in the System namespace. For each data type, a short name, or alias, is provided. For instance, int is the short name for System.Int32 and double is the short form of System.Double.

Basically, it's saying the right thing. In Java, Integer class is a wrapper for int primitive type. In C#, int is an alias for System.Int32 structure. The first paragraph is about Java and doesn't apply to C#.


In .NET, the terminology is as follows:

A primitive type is a type that has IsPrimitive property set to true. Primitive types are:

The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single.

All primitive types are value types but not vice versa.

A value type is a type that has value semantics, as opposed to reference semantics. The whole value is copied when passed by value (not its reference). Local variables of value types are stored on stack. structs and enums are value types.

As mentioned above, all primitive types are value types. They are structs in the System namespace. In C#, int, double, etc., keywords are basically aliases for those structs.

Mehrdad Afshari
+5  A: 

The first bullet point is correct.

The second is not: the primitive types in .NET are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single. A struct cannot usually be set to null, but there are also nullable value types (Nullable<T>). These are still value types, but there's syntactic sugar in C# to equate "null" with "the null value for the type", which for a nullable value type is an instance where HasValue returns false.

int and System.Int32 are exact synonyms in C#. The former is just an alias for the latter. They compile to exactly the same code.

In C#, classes and interfaces are always reference types. Structs and enums are value types - but there is a boxed equivalent of every struct (other than Nullable<T> which is handled differently by the CLR in terms of boxing). The boxed types don't have separate names, and can't be referred to explicitly in C# (although they can be in C++/CLI). There is no separate wrapper class equivalent like java.lang.Integer in .NET; it would be problematic to introduce such classes as you can create your own value types in .NET, unlike in Java.

For more information on reference types and value types, see my article about it.

Jon Skeet
@Jon edited the question and removed the second bullet point, Instead pointed to your answer.
peter.murray.rust