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我记得读过一些埃里克·利珀特关于这个问题的材料;我不记得它是在这里还是在他的博客上,我花了太多时间沉迷于规范,现在才开始搜索。但我强烈建议你自己看看。即使你没有找到你想要的东西,你肯定会找到好东西。谢谢!我确实读过埃里克·利珀特的博客(不过速度不够快)