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 ex开发者_C百科ecutes successfully:
string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);
I would like to know:
Why does the the first code generate a compile-time error?
What's the difference between the 2 code snippets?
(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
truncatesfoo
(ifoo = Math.Floor(foo)
), whileConvert.ToInt32(foo)
uses half to even rounding (rounds x.5 to the nearest EVEN integer, meaningifoo = Math.Round(foo)
). The result is thus not just implementation-wise, but also numerically not the same.
(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.
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.
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);
}
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.
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"];
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.
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];
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
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
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'.
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.
精彩评论