字符串运算符+源代码在哪里?

约翰·杜

当我检查以下代码时string s = "a" + 1有效。

在工具提示中,Visual Studio显示它使用 string operator + (string left, object right)在此处输入图片说明

无论如何,它在String源代码中没有提到,因为只有==and !=

我绝对可以假设它使用与相似的东西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);

(以下参考)

您可以在Roslyn的BuiltInOperators源代码中看到它们

(int)BinaryOperatorKind.StringConcatenation,
(int)BinaryOperatorKind.StringAndObjectConcatenation,
(int)BinaryOperatorKind.ObjectAndStringConcatenation,

您可以将Kinds跟随BinaryOperatorKind枚举。

StringConcatenation = String | Addition,
StringAndObjectConcatenation = StringAndObject | Addition,
ObjectAndStringConcatenation = ObjectAndString | Addition,

+调用字符串的魔力的结尾部分(在被认为是加法表达式之后)。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);
}

字符串运算符的参考

以下是来自Expressions文章的Addition运算符部分,它是C#规范的一部分。

  • 字符串串联:
string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);

这些二进制+运算符的重载执行字符串连接。如果字符串连接的操作数为null,则替换为空字符串。否则,通过调用从类型对象继承的虚拟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 ==的源代码operator !=

语法可视化器

您可能会或可能不会发现与此问题相关的内容,但是Visual Studio附带了语法可视化工具(视图->其他Windows),该窗口提供了一些代码生成魔术的窗口。

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章