14

I have been working on some code for a while. And I had a question: What's the difference among casting, parsing and converting? And when we can use them?

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
Spoon Yukina
  • 535
  • 4
  • 13
  • 26

7 Answers7

23

Casting is when you take a variable of one type and change it to a different type. You can only do that in some cases, like so:

string str = "Hello";
object o = str;
string str2 = (string)o;  // <-- This is casting

Casting does not change the variable's value - the value remains of the same type (the string "Hello").

Converting is when you take a value from one type and convert it to a different type:

 double d = 5.5;
 int i = (int)d;    // <---- d was converted to an integer

Note that in this case, the conversion was done in the form of casting.

Parsing is taking a string and converting it to a different type by understanding its content. For instance, converting the string "123" to the number 123, or the string "Saturday, September 22nd" to a DateTime.

zmbq
  • 38,013
  • 14
  • 101
  • 171
  • Just to elaborate: Also note that not all casts are valid, it depends if the types are compatible by inheritance. If a conversion operator is defined, then that would go under conversion even if it looks like casting. – David S. Nov 29 '13 at 12:42
  • Hello. Just wondering, do you know which is faster? – fungusanthrax Aug 22 '17 at 14:36
  • Casting doesn't take any time, it is done during compilation, not at run time. Converting (which is a general case of parsing) takes time, but it depends on the types involved. – zmbq Aug 14 '22 at 14:43
12

Casting: Telling the compiler that an object is really something else without changing it (though some data loss may be incurred).

object obj_s= "12345";
string str_i = (string) obj; // "12345" as string, explicit

int small = 12345;
long big = 0;
big = small; // 12345 as long, implicit

Parsing: Telling the program to interpret (on runtime) a string.

string int_s = "12345";
int i = int.Parse(int_s); // 12345 as int

Converting: Telling the program to use built in methods to try to change type for what may be not simply interchangeable.

double dub = 123.45;
int i = System.Convert.ToInt32(dub); // 123 as int
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • You can't implicitly convert a `double` to an `int` as there's (typically) a loss of information. An explicit conversion is required so `i = dub` won't compile. Also, implicit _conversions_ are _not_ casting. They create new data/objects. An "implicit" _cast_ example would be upcasting a subclass to its base class. – Chris Sinclair Sep 23 '12 at 13:45
  • From http://stackoverflow.com/a/4181954/1615483 (on double to int); "you can use a **cast** if you want the default truncate-towards-zero behaviour" – Paul S. Sep 23 '12 at 14:26
  • I will edit for `int` to `long` so there is no doubt though – Paul S. Sep 23 '12 at 14:28
3

These are three terms each with specific uses:

  • casting - changing one type to another. In order to do this, the types must be compatible: int -> object; IList<T> -> IEnumerable<T>
  • parsing - typically refers to reading strings and extracting useful parts
  • converting - similar to casting, but typically a conversion would involve changing one type to an otherwise non-compatible type. An example of that would be converting objects to strings.

A cast from one type to another requires some form of compatibility, usually via inheritance or implementation of an interface. Casting can be implicit or explicit:

class Foo : IFoo {
   // implementations
}

// implicit cast
public IFoo GetFoo() {
   return Foo;
}

// explicit cast
public IFoo GetFoo() {
   return Foo as IFoo;
}

There are quite a few ways to parse. We read about XML parsing; some types have Parse and TryParse methods; and then there are times we need to parse strings or other types to extract the 'stuff we care about'.

int.Parse("3") // returns an integer value of 3
int.TryParse("foo", out intVal) // return true if the string could be parsed; otherwise false

Converting may entail changing one type into another incompatible one. This could involve some parsing as well. Conversion examples would usually be, IMO, very much tied to specific contexts.

IAbstract
  • 19,551
  • 15
  • 98
  • 146
1

casting (casting to work the types need to be compatible) Converting between data types can be done explicitly using a cast

static void _Casting()
{
    int i = 10;
    float f = 0;
    f = i;  // An implicit conversion, no data will be lost.
    f = 0.5F;
    i = (int)f;  // An explicit conversion. Information will be lost.
}

parsing (Parsing is conversion between different types:) converts one type to another type can be called as parsing uisng int.parse

int num = int.Parse("500");

traversing through data items like XML can be also called as parsing

When user-defined conversions get involved, this usually entails returning a different object/value. user-defined conversions usually exist between value types rather than reference types, so this is rarely an issue.

converting Using the Convert-class actually just helps you parse it

for more please refer http://msdn.microsoft.com/en-us/library/ms228360%28VS.80%29.aspx

cc4re
  • 4,821
  • 3
  • 20
  • 27
  • Some slightly incorrect information here. `Casting` should only _treat_ the existing object as a different type (assuming it's a compatible upcast/downcast) and not convert data into a new object. Your example is actually creating new objects/data. `Implicit conversions` _should_ not result in a loss of data, but that is not guaranteed when it comes to user-defined conversions. `Parsing` is typically strictly from a `string` representation to some equivalent object and not from "one type to another type" generally. Conversions can be just as common for reference types as value types. – Chris Sinclair Sep 23 '12 at 13:41
  • @ChrisSinclair i think you have to make a deep look into http://msdn.microsoft.com/en-us/library/ms228360%28VS.80%29.aspx – cc4re Sep 23 '12 at 13:57
1

This question is actually pretty complicated...

Normally, a cast just tells the runtime to change one type to another. These have to be types that are compatible. For example an int can always be represented as a long so it is OK to cast it to a long. Some casts have side-effects. For example, a float will drop its precision if it is cast to an int. So (int)1.5f will result in int value 1. Casts are usually the fastest way to change the type, because it is a single IL operator. For example, the code:

    public void CastExample()
    {
        int i = 7;
        long l = (long)i;
    }

Performs the cast by running the IL code:

conv.i8 //convert to 8-byte integer (a.k.a. Int64, a.k.a. long).

A parse is some function that takes in once type and returns another. It is an actual code function, not just an IL operator. This usually takes longer to run, because it runs multiple lines of code.

For example, this code:

    public void ParseExample()
    {
        string s = "7";
        long l = long.Parse(s);
    }

Runs the IL code:

call       int64 [mscorlib]System.Int64::Parse(string)

In other words it calls an actual method. Internally, the Int64 type provides that method:

    public static long Parse(String s) {
        return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo); 
    }

And Number.Parse:

    [System.Security.SecuritySafeCritical]  // auto-generated 
    internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
        Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes]; 
        NumberBuffer number = new NumberBuffer(numberBufferBytes); 
        Int64 i = 0;

        StringToNumber(value, options, ref number, numfmt, false);

        if ((options & NumberStyles.AllowHexSpecifier) != 0) {
            if (!HexNumberToInt64(ref number, ref i)) { 
                throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
            } 
        } 
        else {
            if (!NumberToInt64(ref number, ref i)) { 
                throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
            }
        }
        return i; 
    }

And so on... so you can see it is actually doing a lot of code.


Now where things get more complicated is that although a cast is usually the fastest, classes can override the implicit and explicit cast operators. For example, if I write the class:

public class CastableClass
{
    public int IntValue { get; set; }

    public static explicit operator int(CastableClass castable)
    {
        return castable.IntValue;
    }
}

I have overridden the explicit cast operator for int, so I can now do:

    public void OverridedCastExample()
    {
        CastableClass cc = new CastableClass {IntValue = 7};
        int i = (int)cc;
    }

Which looks like a normal cast, but in actuality it calls my method that I defined on my class. The IL code is:

call       int32 UnitTestProject1.CastableClass::op_Explicit(class UnitTestProject1.CastableClass)

So anyway, you typically want to cast whenever you can. Then parse if you can't.

CodingWithSpike
  • 42,906
  • 18
  • 101
  • 138
1

Casting: or Parsing

A cast explicitly invokes the conversion operator from one type to another. Casting variables is not simple. A complicated set of rules resolves casts. In some cases data is lost and the cast cannot be reversed. In others an exception is provoked in the execution engine. int.Parse is a simplest method but it throws exceptions on invalid input.

TryParse

int.TryParse is one of the most useful methods for parsing integers in the C# language. This method works the same way as int.Parse. int.TryParse has try and catch structure inside. So, it does not throw exceptions

Convert:

Converts a base data type to another base data type. Convert.ToInt32, along with its siblings Convert.ToInt16 and Convert.ToInt64, is actually a static wrapper method for the int.Parse method.

Using TryParse instead of Convert or Cast is recommended by many programmers.

source:www.dotnetperls.com

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
  • 1
    `TryParse` is not confusing and follows the same pattern as the Dictionary's `TryGetValue`. Also, `TryParse` will throw an exception if the string input is null or empty. – IAbstract Sep 23 '12 at 13:52
1

Different people use it to mean different things. It need not be true outside .net world, but here is what I have understood in .net context reading Eric Lippert's blogs:

All transformations of types from one form to another can be called conversion. One way of categorizing may be

  1. implicit -

    a. representation changing (also called coercion)

    int i = 0;
    double d = i;
    
    object o = i; // (specifically called boxing conversion)
    IConvertible o = i; // (specifically called boxing conversion)
    

    Requires implicit conversion operator, conversion always succeeds (implicit conversion operator should never throw), changes the referential identity of the object being converted.

    b. representation preserving (also called implicit reference conversion)

    string s = "";
    object o = s; 
    
    IList<string> l = new List<string>();
    

    Only valid for reference types, never changes the referential identity of the object being converted, conversion always succeeds, guaranteed at compile time, no runtime checks.

  2. explicit (also called casting) -

    a. representation changing

    int i = 0;
    enum e = (enum)i;
    
    object o = i;
    i = (int)o; // (specifically called unboxing conversion)
    

    Requires explicit conversion operator, changes the referential identity of the object being converted, conversion may or may not succeed, does runtime check for compatibility.

    b. representation preserving (also called explicit reference conversion)

     object o = ""; 
     string s = (string)o;
    

    Only valid for reference types, never changes the referential identity of the object being converted, conversion may or may not succeed, does runtime check for compatibility.

While conversions are language level constructs, Parse is a vastly different thing in the sense it's framework level, or in other words they are custom methods written to get an output from an input, like int.Parse which takes in a string and returns an int.

nawfal
  • 70,104
  • 56
  • 326
  • 368