c# - 字符串运算符 + 源代码在哪里?
问题描述
当我检查以下代码是否string s = "a" + 1
有效时。
在工具提示中,Visual Studio 显示它使用string operator + (string left, object right)
无论如何,它在String 的源代码中没有提到,因为只有==
and !=
。
我绝对可以假设它使用类似于 的东西left + right.ToString()
,但真的想检查它的真实源代码。
PS 在 C# 源代码中不存在它使我对无限的兴趣倍增:)
解决方案
这对我来说是新的,我不是编译器专家,这是我最好的选择。
源代码在哪里?
简短的回答
贯穿.NET Compiler Platform ("Roslyn")的代码。
更长的答案
c# 中有 3 个内置运算符 for string
.
string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);
(参考下文)
BuiltInOperators
您可以在 Roslyn 的课堂源代码中看到它们。
(int)BinaryOperatorKind.StringConcatenation,
(int)BinaryOperatorKind.StringAndObjectConcatenation,
(int)BinaryOperatorKind.ObjectAndStringConcatenation,
您可以按照Kind
s 到BinaryOperatorKind
枚举。
StringConcatenation = String | Addition,
StringAndObjectConcatenation = StringAndObject | Addition,
ObjectAndStringConcatenation = ObjectAndString | Addition,
调用 string.Concat的魔法的最后部分(在它被识别为加法表达式之后)+
似乎发生在RewriteStringConcatenation
方法中。
首先将左侧和右侧转换为字符串,这可能需要调用ToString()
,您可以在其他人发布的 IL 中看到。
// Convert both sides to a string (calling ToString if necessary)
loweredLeft = ConvertConcatExprToString(syntax, loweredLeft);
loweredRight = ConvertConcatExprToString(syntax, loweredRight);
很多行之后,RewriteStringConcatenationNNNxprs
可能会调用其中一个方法,例如RewriteStringConcatenationTwoExprs
提供特殊方法的string.Concat
方法。
private BoundExpression RewriteStringConcatenationTwoExprs(SyntaxNode syntax, BoundExpression loweredLeft, BoundExpression loweredRight)
{
Debug.Assert(loweredLeft.HasAnyErrors || loweredLeft.Type.IsStringType());
Debug.Assert(loweredRight.HasAnyErrors || loweredRight.Type.IsStringType());
var method = UnsafeGetSpecialTypeMethod(syntax, SpecialMember.System_String__ConcatStringString);
Debug.Assert((object)method != null);
return (BoundExpression)BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight);
}
字符串运算符的参考
以下来自表达式文章的加法运算符部分,它是 C# 规范的一部分。
- 字符串连接:
string operator +(string x, string y); string operator +(string x, object y); string operator +(object x, string y);
二元 + 运算符的这些重载执行字符串连接。如果字符串连接的操作数为 null,则替换为空字符串。否则,通过调用从类型 object 继承的虚拟 ToString 方法,将任何非字符串参数转换为其字符串表示形式。如果 ToString 返回 null,则替换为空字符串。
using System; class Test { static void Main() { string s = null; Console.WriteLine("s = >" + s + "<"); // displays s = >< int i = 1; Console.WriteLine("i = " + i); // displays i = 1 float f = 1.2300E+15F; Console.WriteLine("f = " + f); // displays f = 1.23E+15 decimal d = 2.900m; Console.WriteLine("d = " + d); // displays d = 2.900 } }
字符串连接运算符的结果是一个字符串,它由左操作数的字符和右操作数的字符组成。字符串连接运算符从不返回空值。如果没有足够的内存可用于分配结果字符串,则可能会引发 System.OutOfMemoryException。
用于字符串的 .NET 4.8 的源代码在此处,但它仅包含用于operator ==
和.NET 的源代码operator !=
。
语法可视化器
您可能会或可能不会发现这与此问题相关,但 Visual Studio 带有语法可视化器(视图 -> 其他窗口),它为代码生成的一些魔力提供了一个窗口。
推荐阅读
- flutter - 发送邮件后的消息(mailer:flutter)
- python-3.x - Sympy解决返回`NoneType object not scriptable`
- javascript - React:带有冗余导入语句的捆绑包大小
- c - 分段错误会在 3 天后杀死我
- html - 如何使切换按钮边框(如图所示)不可见?
- javascript - 使用 React 更新功能组件中的数组状态
- list - 使用 NLTK 和 beautifulsoup 进行情绪分析
- cakephp - 在 where 子句 cakephp 中使用不等于
- ssh - “'ssh' 未被识别为内部或外部命令”
- python - 使用python将json数据插入postgresql表