none
Difference between C# primitive and Java Primitve Data types

    Question

  • Hi i am a bit confused about C# primitve types . For each primitive data type(non object) 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.

    But it seems to me that in C# all the data types are primitive types(objects). For example string is short for System.String and int is short for System.Int32. So is it safe to assume that primitves in C# are all objects .. and comments on this would be appreciated


     

    A candle loses nothing by lighting another candle.
    Tuesday, July 26, 2011 3:17 PM

Answers

  • Your final conclusion is effectively the case, though not entirely accurate (the details get nasty).  It's true for variables defined within an executing code block (ie: a method, constructor, or property accessor) - but it's not necessarily globally true.

     

    If you look at the C# object hierarchy, any object that derives from System.ValueType (including all "primitives" like Int32, UInt64, Double, Single, Boolean, as well as Struct and all custom structs) are copied by value.

     

    They are, when used in a method, allocated on the "stack" (though this is an implementation detail).  That being said, when boxed, they're copied to the "heap".  Also, if a value type is used inside of a reference type, it's allocated on the "heap".  Arrays of value types are also allocated and accessed via a reference, etc. 

     

    If you're really interested in the details, I'd strongly recommend Eric Lippert's series called The Stack Is An Implementation Detail:

    http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

    and

    http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

     

    This is very useful to read, and will explain a lot of this in a lot of detail.

     

    The real thing, in .NET (C#), is that value types have copy-by-value semantics, and reference types have copy-by-reference semantics.  This is really the part that you should focus on (as well as understanding boxing and unboxing), as it's what is truly important in this case.

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    • Marked as answer by Silver_Gates Tuesday, July 26, 2011 5:19 PM
    Tuesday, July 26, 2011 4:25 PM
    Moderator
  • The string class is immutable in C# as well. The only difference between C# and Java is that the string class isn't persistent in C# while it is in Java, but most likely you'll never be in a position where that matters.

    • Marked as answer by Silver_Gates Tuesday, July 26, 2011 5:26 PM
    Tuesday, July 26, 2011 5:22 PM
  • Thanks Reed & tim.. For clearing everything out... one final closing point which i would like to add is the string class in C# is mutable whereas the one in java is immutable..

    A candle loses nothing by lighting another candle.


    This is what I get for ill-thought-out and untested examples. I should have used a struct and a class for my example instead of an int and a string to make things simpler instead of throwing something together really quickly between compiles - it's come back to bite me one more time! In fact, the code I posted will not work like I said.

    Strings in C# are immutable, even though they are reference types. It is a little bit of a weird combination. What actually happens in my Append method above is this:

    1. A reference to the original string "test" is passed in. This is a reference to the actual original string, not a copy as with a value type
    2. original += toAppend internally calls the String.Concat method. Concat adds two strings together and returns the result as a new string. Because the + uses the concat method, it does not change the value of the original variable. This line actually creates a new string, stores the result of appending the two values into it, and then returns the new string to original.

    The end result is that, at the beginning of the method, original == a, but after the += line, original != a.

    This is my mistake for giving you a bad example - I apologize for that. The theory holds true for mutable types, like classes, but the way the string class is implemented (as an immutable type) means that the code I posted is a bad example of the concept.


    Check out My Blog for tech news, development tips, and other information for geeks like me.
    • Marked as answer by Silver_Gates Tuesday, July 26, 2011 5:45 PM
    Tuesday, July 26, 2011 5:25 PM

All replies

  • In Java, each primitive type has a matching reference type. Like the examples you mentioned - int is a primitive, and Int32 is the reference type that wraps int. These are technically two different types, and you can't always implicitly convert between them.

    In C#, the main difference has to do with structs. Basically a struct is a complex type - it can include methods, fields, etc just like a class can. The main difference is that a struct is a value type. It is allocated on the stack instead of the heap, and when it is passed as a parameter it is passed by value instead of by reference. Structs mean that even value types in C# can contain methods and fields, so there is no need to create a reference-type wrapper to hold them. We can have an int, which is treated as a value type and works like a good little value type should, but it contains all of the methods and fields needed to interact with it.

    Like you mentioned, C# provides int, string, bool, etc. as macros for these structs. We don't want to have to think consciously about the fact that int is really the same as Int32, and we don't want to have to type out Int32 all the time. It also helps make the language syntax friendlier to programmers with a Java or C background.

     

    EDIT: I should have been clearer, like GreatVolk mentioned, System.String is a reference type. The others (int, bool, etc) are value types. String is always the magical exception.


    Check out My Blog for tech news, development tips, and other information for geeks like me.
    Tuesday, July 26, 2011 3:37 PM
  • No.

    System.String is a reference type.

    System.Int32 is a value type.

     

    Reference types behave like objects. Value types behaves like primitives. You can design your own "primitives" by using the keyword "struct" instead of class.

    There are no direct "wrapper classes" for primitives in C#. You can "box" them into an object:

    int x = 5;
    int? myReference = x;
    
    


    here the ?-types of struct-types/primitives are the wrapper classes...

    Tuesday, July 26, 2011 3:38 PM
  • System.Int32, System.Double are both structures.

    int and double are merely an alias to the System type.


    John Grove, MCC - Senior Software Engineer
    Tuesday, July 26, 2011 3:39 PM
  •  

    But it seems to me that in C# all the data types are primitive types(objects). For example string is short for System.String and int is short for System.Int32. So is it safe to assume that primitves in C# are all objects .. and comments on this would be appreciated

    There are actually two distinctly different types of objects (three if you count pointers) in C# - Value types and Reference Types.  Which is which has already been described in this thread, so I won't repeat that...

     

    Your comment about being "safe to assume that primitives in C# are all objects" is true, but also has some side effects.  You can assume that all reference type primitives are objects, and will act as you'd expect any "java object" to act.  Value types, on the other hand, do have some unusual behavior due to boxing and unboxing when you treat them as System.Object.  This is something worth understanding if you're going to use C#.

     

    While you can treat an int (System.Int32) as an object (System.Object), there are some consequences to doing so, and the behavior can change.  First off, there's a performance penalty associated with boxing and unboxing, so when you do this:

    int a = 3;
    object b = a; // Box "a" into "b"
    
    // ...
    
    int c = (int)b; // Unbox the object in "a" and cast to int
    


    There's a lot more overhead than if you declare "b" as an int.

     

    Also, there is the potential for run time errors that are less than obvious, ie:

    int a = 3;
    object b = a;
    
    uint c = (uint)a; // This is a valid conversion, and is fine
    uint d = (uint)b; // This will raise an exception! You can't unbox + change type in one operation
    


    Granted, this is rare - in general, you can treat any type in C# as an object - but if you work with Value types, you should be aware that there are side effects of doing so.

     

    This, btw, is one huge reason C# generics are very useful - above and beyond the type safety they provide.  The design of C#'s Generics really shine when you look at how they eliminate boxing and unboxing...

     

     

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    • Proposed as answer by EverForest Tuesday, July 26, 2011 5:01 PM
    Tuesday, July 26, 2011 4:02 PM
    Moderator
  • Thanks Tim for taking the time to answer my question. I am having a little trouble comprehending your answer. Here is what i concluded from your answer, let me know if i am right or wrong and if i am missing anything.. C# basically has 2 main types structs and classes.. all the built in types are structs example a System.Int32 which has an alias of int. Structs are passed by value created on stack (like java primitives) and classes are created on heap and passed as reference..

    A candle loses nothing by lighting another candle.
    Tuesday, July 26, 2011 4:10 PM
  • Hi Reed I would definitely like to hear your opinion on the final conclusion i drew..

    A candle loses nothing by lighting another candle.
    Tuesday, July 26, 2011 4:12 PM
  • Your final conclusion is effectively the case, though not entirely accurate (the details get nasty).  It's true for variables defined within an executing code block (ie: a method, constructor, or property accessor) - but it's not necessarily globally true.

     

    If you look at the C# object hierarchy, any object that derives from System.ValueType (including all "primitives" like Int32, UInt64, Double, Single, Boolean, as well as Struct and all custom structs) are copied by value.

     

    They are, when used in a method, allocated on the "stack" (though this is an implementation detail).  That being said, when boxed, they're copied to the "heap".  Also, if a value type is used inside of a reference type, it's allocated on the "heap".  Arrays of value types are also allocated and accessed via a reference, etc. 

     

    If you're really interested in the details, I'd strongly recommend Eric Lippert's series called The Stack Is An Implementation Detail:

    http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

    and

    http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

     

    This is very useful to read, and will explain a lot of this in a lot of detail.

     

    The real thing, in .NET (C#), is that value types have copy-by-value semantics, and reference types have copy-by-reference semantics.  This is really the part that you should focus on (as well as understanding boxing and unboxing), as it's what is truly important in this case.

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    • Marked as answer by Silver_Gates Tuesday, July 26, 2011 5:19 PM
    Tuesday, July 26, 2011 4:25 PM
    Moderator
  • Thanks Reed will definitely read it.. but just to be sure by value types  u mean (struct types) and  by reference types you mean (class types) ??

    A candle loses nothing by lighting another candle.
    Tuesday, July 26, 2011 4:43 PM
  • Thanks .. but just to be sure by value types  u mean (struct types) and  by reference types you mean (class types) ??

    A candle loses nothing by lighting another candle.


    Yes, that's correct.

    Reed is faster and more thorough than I am. All-in-all, you have the right idea. There are some low level implementation details that may make some of the things you're saying technically inaccurate (i.e. heap vs stack allocation, like Reed pointed out) but you have the right idea.

    A value type just means that, whenever you pass the type into a method, a separate copy is actually passed. Int is a good example, like here:

    int a = 10;
    Increment(a);
    
    public void Increment(int starting)
    {
        starting = starting + 1;
    }
    

    When Increment is called, the number 10 is passed in. This is a separate copy of the value of 'a'. Even if we change starting inside of the method, the original variable 'a' is not changed. The Increment method doesn't actually work. We only change the internal copy of the value, not the original variable.

    Reference types are the opposite. When they are passed to the method, instead of creating an entire copy, a reference to the original variable is passed. Effectively, this means the method is able to access all of the guts of the original variable, rather than having its own copy:

    string a = "test";
    Append(a, "_extra");
    
    public void Append(string original, string toApped)
    {
        original += toAppend;
    }
    

    Because string is a reference type, the Append method actually works. We're not working with our own string variable which just contains the same value, we are actually interacting with the original string directly. This allows the Append method to modify the original string, which isn't directly possible with value types.

    There are performance considerations and other implementation details for both approaches. Each has its benefits and costs - which is why C# exposes both structs and classes.


    Check out My Blog for tech news, development tips, and other information for geeks like me.
    • Marked as answer by Silver_Gates Tuesday, July 26, 2011 5:19 PM
    • Unmarked as answer by Silver_Gates Tuesday, July 26, 2011 5:45 PM
    Tuesday, July 26, 2011 4:57 PM
  • The string class is immutable in C# as well. The only difference between C# and Java is that the string class isn't persistent in C# while it is in Java, but most likely you'll never be in a position where that matters.

    • Marked as answer by Silver_Gates Tuesday, July 26, 2011 5:26 PM
    Tuesday, July 26, 2011 5:22 PM
  • Thanks Reed & tim.. For clearing everything out... one final closing point which i would like to add is the string class in C# is mutable whereas the one in java is immutable..

    A candle loses nothing by lighting another candle.


    This is what I get for ill-thought-out and untested examples. I should have used a struct and a class for my example instead of an int and a string to make things simpler instead of throwing something together really quickly between compiles - it's come back to bite me one more time! In fact, the code I posted will not work like I said.

    Strings in C# are immutable, even though they are reference types. It is a little bit of a weird combination. What actually happens in my Append method above is this:

    1. A reference to the original string "test" is passed in. This is a reference to the actual original string, not a copy as with a value type
    2. original += toAppend internally calls the String.Concat method. Concat adds two strings together and returns the result as a new string. Because the + uses the concat method, it does not change the value of the original variable. This line actually creates a new string, stores the result of appending the two values into it, and then returns the new string to original.

    The end result is that, at the beginning of the method, original == a, but after the += line, original != a.

    This is my mistake for giving you a bad example - I apologize for that. The theory holds true for mutable types, like classes, but the way the string class is implemented (as an immutable type) means that the code I posted is a bad example of the concept.


    Check out My Blog for tech news, development tips, and other information for geeks like me.
    • Marked as answer by Silver_Gates Tuesday, July 26, 2011 5:45 PM
    Tuesday, July 26, 2011 5:25 PM
  • Hi ScottyDoesKnow.. could you point out a little reference to persistance with regards to strings.. and what persistance is itself..  unfortunately my familiarity with this topic is not quiet upto the mark.. and I cant find any articles online on this topic.. Thanks..

    A candle loses nothing by lighting another candle.
    Tuesday, July 26, 2011 5:29 PM
  • Like I said, the difference will likely never matter to you. But if you want to learn more here's a good article on the subject:

    http://blogs.msdn.com/b/ericlippert/archive/2011/07/19/strings-immutability-and-persistence.aspx

    Tuesday, July 26, 2011 5:36 PM
  • @Tim thanks.. for taking the time and posting back. I must admit that example kind of had me going. I remember earlier I used to pass strings around by ref to other methods .. using the ref keyword and that made me think "why on earth did I ever do that for" . Never the less thanks for clearing that up and I really appreciate it...

    A candle loses nothing by lighting another candle.
    Tuesday, July 26, 2011 5:45 PM