none
Type Casting in C#

    Question

  • Hi,

     

    I am Using VS2005 and framework 2.0

     

    I have read about boxing and unboxing [ ref: http://msdn2.microsoft.com/en-us/library/yz2be5wk.aspx ] at msdn and it is costing more in term of memory usage on the heap, and anybody tell me do i use typecasting or System.Convert.ToInt32 ot ToDateTime etc.

    e.g:

     

    TypeCasting:

    int intABC;

    intABC = (int)DropDownList.SelectedValue;

     

    Converting:

    int intABC;

    intABC = System.Convert.ToInt32(DropDownList.SelectedValue);

     

    From above example which result to a good and optimized performance in terms of memory usage on the heap for objects

     

     Above was just an example for which selectedvalue returns string, but what if and return type is just an object and i want to convert to int/ string/ etc..

     

    This is required if i am using any type which returns an object type value

     

    Is type conversion is equally costing in vb.net though programmer is not doing any casting, but i assume the CLR is doing it return.

     

    My concern from this post is is casting or converting really consume response time to display output to user in ASP.NET and / or the memory of the server is used a lot as boxing creates objects on heap.

     

    Regards,

    Hardik I. Shah

    Friday, April 06, 2007 7:13 AM

Answers

  • You are not going to really notice the performance hit of boxing/casting unless you do so a bunch of times (like over 1000).  Boxing/unboxing/casting serve different purposes so you should not confuse them.  In the general case you have an object and you want to get a value type out of it.  In this case you would do typecast like so:

    Code Snippet
    int number = (int)objValue;

     

    This is technically unboxing but an unboxing operation does not require any memory (it was already allocated for the object).  It simply requires a field access (effectively).

     

    Boxing is the process of converting a value type to a reference type and is generally only seen when calling methods that require object parameters like so:

    Code Snippet
    string str = String.Format("Today is {0}.  It is {1} degrees outside.", DateTime.Now, nDegrees);

     

     Here there are two boxing operations (one for each parameter to String.Format).  This does allocate memory (1 object for each one) but otherwise will have no impact.  One of the reasons generics were introduced was to get around this boxing issue because often times we don't care about the actual type of a parameter so we use object but that requires boxing.

     

    The biggest issue with boxing is the fact that you are not actually accessing the original object so any changes that you make to the boxed object will not impact the original object.  This causes some difficulties if you're not aware of it.  For example:

    Code Snippet

    void Add ( object value1, object value2 )
    {
       int num1 = (int)value1;
       int num2 = (int)value2;

       num1 += num2;

     value1 = num1;
    }

     

    Ignoring the fact that you'd never write code like this it also won't work properly.  Because of boxing any int you pass to the method will be wrapped in an object instance.  After the method is complete the object instance goes away.  The original value type is never modified.

     

    Now for your concern about memory and performance.  Unless you're doing this 1000s of times you will not notice performance.  As far as memory goes you will eat up extra memory but in the long term you won't really notice because the memory will be reclaimed long before you actually run out.  So, in general, you should try to avoid boxing/unboxing when possible (by using properly typed variables and parameters) but don't go out of your way to avoid a boxing situation.  For example it would be overkill (and worse on performance) to create a custom class to wrap an int value just so you can pass it around as an object parameter to avoid boxing.

     

    A final note about value types.  As of v2 of .NET structures that implement interfaces can be passed as instances of the interface without boxing.  Prior to v2 (if I remember correctly) a structure would be boxed even if it implemented the interface.

     

    Michael Taylor - 4/6/07

    http://p3net.mvps.org

     

     

    Friday, April 06, 2007 12:32 PM
    Moderator

All replies

  • You are not going to really notice the performance hit of boxing/casting unless you do so a bunch of times (like over 1000).  Boxing/unboxing/casting serve different purposes so you should not confuse them.  In the general case you have an object and you want to get a value type out of it.  In this case you would do typecast like so:

    Code Snippet
    int number = (int)objValue;

     

    This is technically unboxing but an unboxing operation does not require any memory (it was already allocated for the object).  It simply requires a field access (effectively).

     

    Boxing is the process of converting a value type to a reference type and is generally only seen when calling methods that require object parameters like so:

    Code Snippet
    string str = String.Format("Today is {0}.  It is {1} degrees outside.", DateTime.Now, nDegrees);

     

     Here there are two boxing operations (one for each parameter to String.Format).  This does allocate memory (1 object for each one) but otherwise will have no impact.  One of the reasons generics were introduced was to get around this boxing issue because often times we don't care about the actual type of a parameter so we use object but that requires boxing.

     

    The biggest issue with boxing is the fact that you are not actually accessing the original object so any changes that you make to the boxed object will not impact the original object.  This causes some difficulties if you're not aware of it.  For example:

    Code Snippet

    void Add ( object value1, object value2 )
    {
       int num1 = (int)value1;
       int num2 = (int)value2;

       num1 += num2;

     value1 = num1;
    }

     

    Ignoring the fact that you'd never write code like this it also won't work properly.  Because of boxing any int you pass to the method will be wrapped in an object instance.  After the method is complete the object instance goes away.  The original value type is never modified.

     

    Now for your concern about memory and performance.  Unless you're doing this 1000s of times you will not notice performance.  As far as memory goes you will eat up extra memory but in the long term you won't really notice because the memory will be reclaimed long before you actually run out.  So, in general, you should try to avoid boxing/unboxing when possible (by using properly typed variables and parameters) but don't go out of your way to avoid a boxing situation.  For example it would be overkill (and worse on performance) to create a custom class to wrap an int value just so you can pass it around as an object parameter to avoid boxing.

     

    A final note about value types.  As of v2 of .NET structures that implement interfaces can be passed as instances of the interface without boxing.  Prior to v2 (if I remember correctly) a structure would be boxed even if it implemented the interface.

     

    Michael Taylor - 4/6/07

    http://p3net.mvps.org

     

     

    Friday, April 06, 2007 12:32 PM
    Moderator
  • I'm faced with a dilema here.

     

    I've created 2 objects which their name says it all.

     

    DataOLE AccessTable

    DataSQL SQLTable

     

    Now when I need one , I declare an instance for it 

     

    AccessTable = new DataOLE(...);

     

    but now I would like to implement a way to get the proper object according to a configuration that the customer asked.

     

    Let say, a form that asks for which type of database would you like to work with

     

    Now that I know that,  how to get the proper object according to the customer needs ?

     

    I tought of something like

     

    object Table;

     

     

    if(CustomerNeedSQL)

    Table = new DataSQL(...)

    else

    Table = new DataOLE(...)

     

    Now the problem is how to use "Table" so we don't have to cast ?

     

     

     

    Tuesday, November 13, 2007 8:43 PM
  • Solved it by using Base class for connection and data manipulation

    I did learn quiet a lot since this message Smile

     

    Happy programming

     

    Thursday, May 22, 2008 12:51 PM
  • there will be no real noticeable performance difference, however I did want to point out that instead of doing
    int IntABC;

    IntABC = 3;

    you can simply initialize the int with the value, like

    int IntABC = 3;

    Sunday, June 24, 2012 9:49 AM
  • Sunday, June 24, 2012 12:14 PM