When comparing a string and an int, what is the difference between converting them both to a string vs converting them both to an int?
What is the difference (both in terms of correctness and performance) between doing the following comparisons.
int a = 100;
string b = "100";
if (a == Convert.ToInt16(b))
//Do something
if (a.ToString() == b)
//Do Something
If I have a string value that is always an int (say for storing an int in a开发者_开发问答 hidden field on a webpage) I have always compared both values as integers because that is what the data is representing, but I would like a more technical reason.
Comparing strings somewhat works for equality and inequality, but not for other comparisons.
For instance, a < Convert.ToInt16(b)
is not the same thing as a.ToString() < b
.
For that reason alone, I personally always prefer comparing numbers instead of strings.
If the string is
0100
, the second option will incorrectly returnfalse
If the string happens to not contain an integer (eg, an attacker modified it), the first option will throw an exception
I would favor ToString() on the int just because it's a type-safe conversion. If your variable b above somehow got a non-numeric value, the conversion would cause an exception.
Converting to int is more accurate for a variety of reasons that others have pointed out. Just be sure you're handling the exception case where b isn't numeric.
Conversion to int leads to smaller MSIL. The first test leads to a call to convert method then then comparison is done within the registers of the virtual machine. In second example, the conversion to string is one call (ToString()) and then comparison to equality is another.
So moral of the story is that if I have to do a lot of such comparisons, I will stick to first method.
method f1(): I convert string to int
.method private hidebysig static void f1() cil managed
{
// Code size 29 (0x1d)
.maxstack 2
.locals init ([0] int32 a,
[1] string b)
IL_0000: ldc.i4.s 100
IL_0002: stloc.0
IL_0003: ldstr "100"
IL_0008: stloc.1
IL_0009: ldloc.0
IL_000a: ldloc.1
IL_000b: call int16 [mscorlib]System.Convert::ToInt16(string)
IL_0010: bne.un.s IL_001c
IL_0012: ldstr "Test 1"
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: ret
} // end of method Program::f1
method f2(): I convert int to string
.method private hidebysig static void f2() cil managed
{
// Code size 35 (0x23)
.maxstack 2
.locals init ([0] int32 a,
[1] string b)
IL_0000: ldc.i4.s 100
IL_0002: stloc.0
IL_0003: ldstr "100"
IL_0008: stloc.1
IL_0009: ldloca.s a
IL_000b: call instance string [mscorlib]System.Int32::ToString()
IL_0010: ldloc.1
IL_0011: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_0016: brfalse.s IL_0022
IL_0018: ldstr "Test 2"
IL_001d: call void [mscorlib]System.Console::WriteLine(string)
IL_0022: ret
} // end of method Program::f2
Technical reason? Perhaps because they are stored as strings initially, you are assuring an accurate comparison is made by an int conversion, because for a string comparison, "0100" != "100" which is clearly undesirable
what comparing strings actually does is that it compares character by character. But comparing ints compares the bits which is faster.
精彩评论