与#x2B;及;用于在VB.NET中连接字符串

与#x2B;及;用于在VB.NET中连接字符串,vb.net,string,Vb.net,String,在VB.NET中连接字符串的+和&之间有什么区别?连接字符串时无: Dim string1 As String = "A" + "B" Dim string2 As String = "A" & "B" If string1.Equals(string2) And string2.Equals(string1) Then Debugger.Break() End If &运算符始终确保两个操作数都是字符串,而+运算符则查找与操作数匹配的

在VB.NET中连接字符串的
+
&
之间有什么区别?

连接字符串时无:

    Dim string1 As String = "A" + "B"
    Dim string2 As String = "A" & "B"

    If string1.Equals(string2) And string2.Equals(string1) Then
        Debugger.Break()
    End If

&运算符始终确保两个操作数都是字符串,而+运算符则查找与操作数匹配的重载

表达式
1&2
给出值“12”,而表达式1+2给出值3


如果两个操作数都是字符串,则结果没有差异。

在大多数情况下没有差异。但是,最佳做法是:

“+”应该保留用于整数加法,因为如果您不使用选项Strict On,那么您可能会将以下情况弄得一团糟:

Input+12
可能会为您提供
20
而不是
812
。在输入来自POST/GET的ASP.NET应用程序中,这可能特别糟糕

简单地说:对于连接字符串,始终使用“&”而不是“+”


显然,在合适的地方使用:)

如果两个操作数都是字符串,则没有区别。但是,如果一个操作数是字符串,一个是数字,则会遇到问题,请参阅下面的代码

"abc" + "def" = "abcdef"
"abc" & "def" = "abcdef"
"111" + "222" = "111222"
"111" & "222" = "111222"
"111" & 222 = "111222"
"111" + 222 = 333
"abc" + 222 = conversion error

因此,我建议在要连接时始终使用
&
,因为您可能试图将整数、浮点、十进制连接到字符串,这将导致异常,或者充其量不会执行您可能希望它执行的操作。

运算符可以是加法或连接。&只是串联。如果表达式都是字符串,则结果将是相同的


我在处理字符串时使用&,在处理数字时使用+,所以我的意图永远不会混淆。如果错误地使用+,一个表达式是字符串,一个表达式是数字,则可能会产生不期望的结果。

如果这两种类型都是静态类型,则代码之间的差异为零。两者都将解析为成员(这是
+
对字符串所做的)

但是,如果对象不是字符串的强类型,那么VisualBasic后期绑定将启动并走两条截然不同的路线。
+
版本将尝试执行添加操作,该操作会尝试添加对象。这将以各种方式尝试将两个值转换为一个数字,然后将它们相加

&
运算符将尝试连接。VisualBasic运行时将通过各种转换方式将两个值转换为字符串。然后它将
String.Concat
结果。

正如你在下面看到的。这两行代码编译为完全相同的CIL代码:

Module Module1

    Sub Main()
        Dim s1 As String = "s1"
        Dim s2 As String = "s2"
        s2 += s1
        s1 &= s2
    End Sub

End Module
编译到(注意
System.String::Concat
):


直接来自MSDN文档:

两个串联运算符之间的差异

+运算符(Visual Basic)的主要目的是添加两个 数字。但是,它也可以将数字操作数与字符串连接起来 操作数。+运算符有一组复杂的规则,用于确定 是添加、连接、发出编译器错误信号,还是抛出 运行时InvalidCastException异常

&运算符(Visual Basic)仅为字符串操作数定义,并且 它总是将其操作数扩展为字符串,而不管 选项严格。建议使用&运算符进行字符串连接 因为它是专门为字符串定义的,减少了您的机会 产生一个非预期的转换


请相信MSDN!:-)

或者始终严格执行选项,在这种情况下,您无需担心。Option Strict On还有许多其他优点:字符串连接的
&
存在问题。从“无论选项Strict的设置如何,&运算符总是将其操作数扩展到字符串”。因此,例如
“Hello”&2.5
将使用区域设置将2.5静默地转换为字符串(您可能会得到
“2.5”
“2,5”
)。好吧,如果那是你想要的。我非常非常愿意被强迫明确地指定。@MarkJ哦,是的,如果你不看的话,那些地方性的东西真的会让你着迷。尤其是在web服务器上。如果您有一组web服务器,您应该确保它们都配置为相同的区域设置,这样可以解决数字和日期的wierd格式问题。为完整起见,还应该注意执行
“abc”&222
“abc222”
)时返回的内容.让我提一下最后一行的
333
实际上是
System.Double
类型。谢谢Aliostad,这是一个完美的总结。我最好奇的是(在我的问题中,我可能应该更清楚地概括一下)它是如何处理的。String+String(只要它们都是String)与String&String相同(不管+运算符有多复杂的规则)。没有问题。使用ILDASM查看IL代码总是很好的。最初不熟悉,但逐渐习惯。+运算符仅在
选项Strict
Off
时执行隐式转换。但是&运算符将执行到字符串的隐式转换,而不考虑
选项Strict
设置。“无论选项Strict的设置如何,&运算符始终将其操作数加宽为字符串”。因此,例如
“Hello”&2.5
将使用区域设置将2.5静默地转换为字符串(您可能会得到
“2.5”
“2,5”
)。如果这是您想要的,那么很好。另外值得一提的是,
&
操作符忽略了Strict选项。从“无论选项Strict的设置如何,&运算符总是将其操作数扩展到字符串”。因此,例如
“Hello”&2.5
将使用区域设置(您可能会得到
“2.5”

.method public static void  Main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size       31 (0x1f)
.maxstack  2
.locals init ([0] string s1,
       [1] string s2)
IL_0000:  nop
IL_0001:  ldstr      "s1"
IL_0006:  stloc.0
IL_0007:  ldstr      "s2"
IL_000c:  stloc.1
IL_000d:  ldloc.1
IL_000e:  ldloc.0
IL_000f:  call       string [mscorlib]System.String::Concat(string,
                                                          string)
IL_0014:  stloc.1
IL_0015:  ldloc.0
IL_0016:  ldloc.1
IL_0017:  call       string [mscorlib]System.String::Concat(string,
                                                          string)
IL_001c:  stloc.0
IL_001d:  nop
IL_001e:  ret
} // end of method Module1::Main