当比较字符串和整型时,将它们都转换为字符串与将它们都转换为整型的区别是什么?
本文关键字:转换 整型 字符串 区别 是什么 比较 | 更新日期: 2023-09-27 18:03:36
进行以下比较的区别(在正确性和性能方面)是什么?
int a = 100;
string b = "100";
if (a == Convert.ToInt16(b))
//Do something
if (a.ToString() == b)
//Do Something
如果我有一个字符串值,它总是一个int(比如在网页上的隐藏字段中存储一个int),我总是将两个值作为整数进行比较,因为这是数据所表示的,但我想要一个更技术性的原因。
比较字符串在某种程度上适用于相等和不相等,但不适用于其他比较。
例如,a < Convert.ToInt16(b)
和a.ToString() < b
不是一回事。
仅仅因为这个原因,我个人更喜欢比较数字而不是字符串。
-
如果字符串是
0100
,第二个选项将错误地返回false
-
如果字符串碰巧不包含整数(例如,攻击者修改了它),第一个选项将抛出异常
我倾向于在int上使用ToString(),因为它是一种类型安全的转换。如果上面的变量b以某种方式得到了非数值,则转换将导致异常。
转换为int更准确。只要确保您正在处理b不是数字的异常情况。
转换为int会导致更小的MSIL。第一个测试导致调用convert方法,然后在虚拟机的寄存器内进行比较。在第二个例子中,转换为字符串是一次调用(ToString()),然后比较相等是另一次调用。
所以这个故事的寓意是,如果我必须做很多这样的比较,我会坚持第一种方法。
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
方法f2():将int转换为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
技术原因?也许因为它们最初是作为字符串存储的,所以要确保通过int转换进行准确的比较,因为对于字符串比较,"0100" != "100"显然是不希望出现的
比较字符串实际上做的是逐个字符比较。但是比较int比较bits更快