简体   繁体   中英

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 return false

  • 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM