C#和#x2B;运算符调用string.concat函数?
可能重复:C#和#x2B;运算符调用string.concat函数?,c#,string,operator-overloading,concatenation,C#,String,Operator Overloading,Concatenation,可能重复: 我刚发现我们写了这样一行: string s = "string"; s = s + s; // this translates to s = string.concat("string", "string"); 但是,我通过reflector打开了string类,我不知道这个+操作符在哪里重载了?我可以看到==和!=车辆超载 [TargetedPatchingOptOut("Performance critical to inline across NGen image bou
我刚发现我们写了这样一行:
string s = "string";
s = s + s; // this translates to s = string.concat("string", "string");
但是,我通过reflector打开了string类,我不知道这个+操作符在哪里重载了?我可以看到==和!=车辆超载
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public static bool operator ==(string a, string b)
{
return string.Equals(a, b);
}
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public static bool operator !=(string a, string b)
{
return !string.Equals(a, b);
}
那么,当我们使用+组合字符串时,为什么会调用concat呢
谢谢。代码
public string Foo(string str1, string str2)
{
return str1 + str2;
}
给出以下IL:
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: call string [mscorlib]System.String::Concat(string, string)
IL_0008: stloc.0
IL_0009: br.s IL_000b
IL_000b: ldloc.0
IL_000c: ret
编译器(至少是VisualStudio2010中的编译器)执行此任务,并且不存在+
重载
那么,当我们使用+组合字符串时,为什么会调用concat呢
C#规范第7.7.4节“加法运算符”定义了字符串的二进制加法运算符,其中运算符返回操作数的串联
CLI规范中的System.String
定义包括几个Concat
重载,但没有+
运算符。(我没有一个明确的答案来解释这一遗漏,但我想这是因为有些语言定义了字符串连接的操作符而不是+
。)
考虑到这两个事实,C#编译器编写器最合理的解决方案是在编译
+(String,String)
运算符时发出对String.Concat
的调用。@MichaelPetrotta这不是该问题的重复。链接的问题实际上涉及到不断的折叠。@phoog,我有点同意你的观点,因为这个问题没有涵盖这一点,但Jon的回答准确地回答了VVV的问题。@MichaelPetrotta,J.Skeet的回答对这个问题有何反应?如果两个字符串被输入为动态,运行时是否硬编码以将添加内容视为String.Concat
?@MichaelPetrotta抱歉,我不清楚。我想强调的是,目前问题的答案是“第7.7.4节”,而乔恩对假设的重复问题的答案是“第7.18节”。Jon的答案和问题是关于常数折叠,而不是+运算符的定义。这个问题是关于+运算符的定义。事实上,这两个问题的共同答案都是“编译器做到了”,但如果我们在规范中寻找“为什么”问题的答案,那么答案就不同了,问题也不是重复的。这个答案只是证实了OP询问的行为;它并没有回答“为什么要这样做?”@phoog,正如你在评论中所说的那样。编译器必须以某种方式实现强制转换,因为+
运算符没有重载。Visual Studio编译器使用string.Concat
。为什么string.Concat
而不是另一个实现?我认为这是因为这很简单,但我不知道真正的答案是否公开。是的,我的回答证实了OP的期望。在某种程度上,+
就像{get;set;}
@phoog一样只是语法上的糖分,但是你的答案显然更好,因为它涉及规范,并且包含更多的“技术背景”。但是它既没有说明为什么string.Concat
而不是其他东西,也没有说明为什么+
不仅仅是过载。为什么+
没有过载:很难找到不做某事的原因。我从来没有对我的老板说“今天,我没有写排序方法,因为……”。因为我不知道原因,我猜测。(我现在有一个模糊的记忆,我曾在第9频道的视频中听到有人讨论过这个问题,但我不确定。)为什么string.Concat
?我得出的结论是,从技术上讲,这是一个实现细节,但很难看出C#编译器的作者如何做出任何其他选择,并且仍然被认为是明智的。+1:对于所有信息……希望有人能提供更多关于issue@KonstantinVasilcov我记得读过一些埃里克·利珀特关于这个问题的材料;我不记得它是在这里还是在他的博客上,我花了太多时间沉迷于规范,现在才开始搜索。但我强烈建议你自己看看。即使你没有找到你想要的东西,你肯定会找到好东西。谢谢!我确实读过埃里克·利珀特的博客(不过速度不够快)