当我检查以下代码string s = "a" + 1是否有效时。
在工具提示中,Visual Studio 显示它使用string operator + (string left, object right)
无论如何,在String 的源代码中没有提到它,因为只有==和!=。
我绝对可以假设它使用类似于 的东西left + right.ToString(),但真的想检查它的真实源代码。
PS C# 源代码中没有它,这让我的兴趣无限增加:)
这对我来说是新的,我不是编译器专家,这是我最好的尝试。
贯穿.NET 编译器平台(“Roslyn”)的代码。
C# 中有 3 个内置运算符string。
string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);
Run Code Online (Sandbox Code Playgroud)
(参考下文)
您可以在 Roslyn 的课堂源代码中看到它们BuiltInOperators。
(int)BinaryOperatorKind.StringConcatenation,
(int)BinaryOperatorKind.StringAndObjectConcatenation,
(int)BinaryOperatorKind.ObjectAndStringConcatenation,
Run Code Online (Sandbox Code Playgroud)
您可以按照Kinds 进行枚举BinaryOperatorKind。
StringConcatenation = String | Addition,
StringAndObjectConcatenation = StringAndObject | Addition,
ObjectAndStringConcatenation = ObjectAndString | Addition,
Run Code Online (Sandbox Code Playgroud)
调用 string.Concat的魔力的结束部分(在它被识别为加法表达式之后)+似乎发生在RewriteStringConcatenation方法中。
首先将左侧和右侧转换为字符串,这可能需要调用ToString(),您可以在其他人发布的IL中看到。
// Convert both sides to a string (calling ToString if necessary)
loweredLeft = ConvertConcatExprToString(syntax, loweredLeft);
loweredRight = ConvertConcatExprToString(syntax, loweredRight);
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
以下内容摘自表达式文章的加法运算符部分,该文章是 C# 规范的一部分。
- 字符串连接:
Run Code Online (Sandbox Code Playgroud)string operator +(string x, string y); string operator +(string x, object y); string operator +(object x, string y);二元 + 运算符的这些重载执行字符串连接。如果字符串连接的操作数为空,则替换为空字符串。否则,任何非字符串参数都会通过调用从类型对象继承的虚拟 ToString 方法转换为其字符串表示形式。如果 ToString 返回 null,则替换为空字符串。
Run Code Online (Sandbox Code Playgroud)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 for string 的源代码位于此处,但它仅包含operator ==和的源代码operator !=。
您可能会或可能不会发现这与这个问题相关,但 Visual Studio 附带了 Syntax Visualiser(视图 -> 其他窗口),它提供了一个了解代码生成的一些魔力的窗口。
| 归档时间: |
|
| 查看次数: |
1056 次 |
| 最近记录: |