66

The following code throws an compile-time error like

Cannot convert type 'string' to 'int'

string name = Session["name1"].ToString();
int i = (int)name;

whereas the code below compiles and executes successfully:

string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);

I would like to know:

  1. Why does the the first code generate a compile-time error?

  2. What's the difference between the 2 code snippets?

A876
  • 471
  • 5
  • 8
balalakshmi
  • 3,968
  • 6
  • 40
  • 48
  • 2
    Interesting. Usually the question is what the difference is between `Convert.ToInt32()` and (`Int32.Parse` or `Int32.TryParse()`) :-) – Joey Oct 22 '09 at 18:24
  • 2
    The first is an explicit cast, you are saying that name IS an int, and should from that point be referenced as such. The second takes the string and does a conversion TO an int, which effectively parses it. – Daniel Dawes Aug 14 '13 at 09:08
  • 1
    @DanielDawes that's a bit misleading - a conversion does occur on a valid cast in C#. For example, the bits stored in floating point number are quite different from the bits stored in the value resulting from a cast to int. – dcstraw Jul 22 '16 at 15:07

12 Answers12

82

(int)foo is simply a cast to the Int32 (int in C#) type. This is built into the CLR and requires that foo be a numeric variable (e.g. float, long, etc.) In this sense, it is very similar to a cast in C.

Convert.ToInt32 is designed to be a general conversion function. It does a good deal more than casting; namely, it can convert from any primitive type to a int (most notably, parsing a string). You can see the full list of overloads for this method here on MSDN.

And as Stefan Steiger mentions in a comment:

Also, note that on a numerical level, (int) foo truncates foo (ifoo = Math.Floor(foo)), while Convert.ToInt32(foo) uses half to even rounding (rounds x.5 to the nearest EVEN integer, meaning ifoo = Math.Round(foo)). The result is thus not just implementation-wise, but also numerically not the same.

Marc Climent
  • 9,434
  • 2
  • 50
  • 55
Noldorin
  • 144,213
  • 56
  • 264
  • 302
  • 28
    Also, note that on a numerical level, (int) foo truncates foo (ifoo = floor(foo)), while ToInt32(foo) uses mathematical rounding (=rounds x.5 to the nearest EVEN integer, meaning ifoo = Math.Round(foo)). The result is thus not just implementation-wise, but also numerically NOT the same. – Stefan Steiger Sep 15 '14 at 14:02
  • Please include @StefanSteiger 's note about rounding within your answer. This can save life (: – Saro Taşciyan Mar 20 '16 at 12:55
  • 1
    Also of interest: (int)UInt32.MaxValue is -1, while Convert.ToInt32(UInt32.MaxValue) throws an OverflowException. – jcox Dec 14 '18 at 16:02
18

(this line relates to a question that was merged) You should never use (int)someString - that will never work (and the compiler won't let you).

However, int int.Parse(string) and bool int.TryParse(string, out int) (and their various overloads) are fair game.

Personally, I mainly only use Convert when I'm dealing with reflection, so for me the choice is Parse and TryParse. The first is when I expect the value to be a valid integer, and want it to throw an exception otherwise. The second is when I want to check if it is a valid integer - I can then decide what to do when it is/isn't.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Third paragraph first sentence seems contradictory on first reading; should it be "*mainly* use `Convert` only when"... or am I just not getting it? – Dax Fohl May 12 '14 at 02:57
  • @DaxFohl, He’s trying to say that if he used `Convert` in a project, it is almost certainly used in conjunction with reflection. I am interpreting this to mean that, being a more generic interface, it’s useful when you do not know whether or not you need to cast some value to `int`, `double`, some other primitive type, or some user type until runtime. E.g., [`Convert.ChangeType()`](https://msdn.microsoft.com/en-us/library/dtb69x08%28v=vs.110%29.aspx) is useful for this. – binki Apr 14 '15 at 18:21
5

To quote from this Eric Lippert article:

Cast means two contradictory things: "check to see if this object really is of this type, throw if it is not" and "this object is not of the given type; find me an equivalent value that belongs to the given type".

So what you were trying to do in 1.) is assert that yes a String is an Int. But that assertion fails since String is not an int.

The reason 2.) succeeds is because Convert.ToInt32() parses the string and returns an int. It can still fail, for example:

Convert.ToInt32("Hello");

Would result in an Argument exception.

To sum up, converting from a String to an Int is a framework concern, not something implicit in the .Net type system.

ecoffey
  • 3,423
  • 4
  • 23
  • 22
4

A string cannot be cast to an int through explicit casting. It must be converted using int.Parse.

Convert.ToInt32 basically wraps this method:

public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }
    return int.Parse(value, CultureInfo.CurrentCulture);
}
Philip Wallace
  • 7,905
  • 3
  • 28
  • 40
4

You're talking about a C# casting operation vs .NET Conversion utilities

  • C# Language-level casting uses parenthesis - e.g. (int) - and conversion support for it is limited, relying on implicit compatibility between the types, or explicitly defined instructions by the developer via conversion operators.
  • Many conversion methods exist in the .NET Framework, e.g. System.Convert, to allow conversion between same or disparate data types.

(Casting) syntax works on numeric data types, and also on "compatible" data types. Compatible means data types for which there is a relationship established through inheritance (i.e. base/derived classes) or through implementation (i.e. interfaces).

Casting can also work between disparate data types that have conversion operators defined.

The System.Convert class on the other hand is one of many available mechanisms to convert things in the general sense; it contains logic to convert between disparate, known, data types that can be logically changed from one form into another.

Conversion even covers some of the same ground as casting by allowing conversion between similar data types.


Remember that the C# language has its own way of doing some things.
And the underlying .NET Framework has its own way of doing things, apart from any programming language.
(Sometimes they overlap in their intentions.)

Think of casting as a C# language-level feature that is more limited in nature, and conversion via the System.Convert class as one of many available mechanisms in the .NET framework to convert values between different kinds.

John K
  • 28,441
  • 31
  • 139
  • 229
1

1) C# is type safe language and doesn't allow you to assign string to number

2) second case parses the string to new variable. In your case if the Session is ASP.NET session than you don't have to store string there and convert it back when retrieving

int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];
Arsen Mkrtchyan
  • 49,896
  • 32
  • 148
  • 184
1

There is not a default cast from string to int in .NET. You can use int.Parse() or int.TryParse() to do this. Or, as you have done, you can use Convert.ToInt32().

However, in your example, why do a ToString() and then convert it back to an int at all? You could simply store the int in Session and retrieve it as follows:

int i = Session["name1"];
Jerry Bullard
  • 6,116
  • 18
  • 27
1

This is already discussed but I want to share a dotnetfiddle.

If you are dealing with arithmetic operations and using float, decimal, double and so on, you should better use Convert.ToInt32().

using System;

public class Program
{
  public static void Main()
  {
    double cost = 49.501;
    Console.WriteLine(Convert.ToInt32(cost));
    Console.WriteLine((int)cost);
  }
}

Output

50
49

https://dotnetfiddle.net/m3ddDQ

Smart Manoj
  • 5,230
  • 4
  • 34
  • 59
I.C
  • 63
  • 1
  • 6
1

Just a brief extra: in different circumstances (e.g. if you're converting a double, &c to an Int32) you might also want to worry about rounding when choosing between these two. Convert.Int32 will use banker's rounding (MSDN); (int) will just truncate to an integer.

Tim Barrass
  • 4,813
  • 2
  • 29
  • 55
0

Convert.ToInt32

    return int.Parse(value, CultureInfo.CurrentCulture);

but (int) is type cast, so (int)"2" will not work since you cannot cast string to int. but you can parse it like Convert.ToInt32 do

Ilya Khaprov
  • 2,546
  • 14
  • 23
0

The difference is that the first snippet is a cast and the second is a convert. Although, I think perhaps the compiler error is providing more confusion here because of the wording. Perhaps it would be better if it said "Cannot cast type 'string' to 'int'.

Joseph
  • 25,330
  • 8
  • 76
  • 125
0

This is old, but another difference is that (int) doesn't round out the numbers in case you have a double ej: 5.7 the ouput using (int) will be 5 and if you use Convert.ToInt() the number will be round out to 6.

Angel Ruiz
  • 31
  • 6