Serhii
Serhii

Reputation: 439

where is the string operator + source code?

As I'm checking the following code string s = "a" + 1 works.

In a tooltip Visual Studio shows that it uses string operator + (string left, object right)enter image description here

Anyway, its not mentioned in the source code of String, as there are only == and !=.

I definitely could assume that it uses something similar to left + right.ToString(), but really want to check its real source code.

P.S. Having it is not present in the C# source code multiplies my interest to infinity :)

Upvotes: 5

Views: 1271

Answers (3)

tmaj
tmaj

Reputation: 35115

This is new for me and I'm not a compiler specialist, here's my best shot.

Where is the source code?

Short answer

Throughout .NET Compiler Platform ("Roslyn")'s code.

Longer answer

There are 3 built-in operators in c# for string.

string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);

(Reference below)

You can see them in Roslyn's source code in BuiltInOperators class.

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

The you can follow the Kinds to the BinaryOperatorKind enum.

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

The end part (after it has been recognized as an addition expression) of the magic of making + into a call to string.Concat seems to happen in RewriteStringConcatenation method.

First the left and the right sides are converted to strings, which may require calling ToString() which you can see in the IL posted by others.

// Convert both sides to a string (calling ToString if necessary)
loweredLeft = ConvertConcatExprToString(syntax, loweredLeft);
loweredRight = ConvertConcatExprToString(syntax, loweredRight);

Many lines after, one of the RewriteStringConcatenationNNNxprs methods may be called, for example RewriteStringConcatenationTwoExprs which provides the special string.Concat method.

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);
}

References for string operators

The following is from Addition operator section of Expressions article which is part of C# specification.

  • String concatenation:
string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);

These overloads of the binary + operator perform string concatenation. If an operand of string concatenation is null, an empty string is substituted. Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. If ToString returns null, an empty string is substituted.

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
    }
}

The result of the string concatenation operator is a string that consists of the characters of the left operand followed by the characters of the right operand. The string concatenation operator never returns a null value. A System.OutOfMemoryException may be thrown if there is not enough memory available to allocate the resulting string.


The source code for .NET 4.8 for string is at here but it only contains sources for operator == and operator !=.

Syntax Visualiser

You may or may not find this relevant to this question, but Visual Studio comes with Syntax Visualiser (View -> Other Windows) which provides a window to some of the magic of code generation.

enter image description here

Upvotes: 5

TimChang
TimChang

Reputation: 2417

I thought that it call ToString() and String.Concat(string , string)

C#

   object aa = 123;
   String a = "123" + aa;

IL

.method public hidebysig 
        instance void DoSomeMoreStuff () cil managed 
    {
        // Method begins at RVA 0x207c
        // Code size 33 (0x21)
        .maxstack 2
        .locals init (
            [0] object,
            [1] string
        )

        IL_0000: nop
        IL_0001: ldc.i4.s 123
        IL_0003: box [System.Private.CoreLib]System.Int32
        IL_0008: stloc.0
        IL_0009: ldstr "123"
        IL_000e: ldloc.0
        IL_000f: brtrue.s IL_0014

        IL_0011: ldnull
        IL_0012: br.s IL_001a

        IL_0014: ldloc.0
        IL_0015: callvirt instance string [System.Private.CoreLib]System.Object::ToString()

        IL_001a: call string [System.Private.CoreLib]System.String::Concat(string, string)
        IL_001f: stloc.1
        IL_0020: ret
    } // end of method SomeClass::DoSomeMoreStuff

Upvotes: 3

Black Frog
Black Frog

Reputation: 11725

It's built into the C# specification. That is why the tooltip show the information it shows, and no additional source code is needed.

Excerpt from Microsoft Doc: + and += operators (C# reference)

The + and += operators are supported by the built-in integral and floating-point numeric types, the string type, and delegate types.

C# is standardized by ECMA International as the ECMA-334 standard and by ISO/IEC as the ISO/IEC 23270 standard. The latest ISO standard ISO/IEC 23270:2018 is available can be downloaded from https://standards.iso.org/ittf/PubliclyAvailableStandards/c075178_ISO_IEC_23270_2018.zip

Excerpt From ISO:

12.9.5 Addition operator For an operation of the form x + y, binary operator overload resolution (§12.4.5) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator

12.4.5 Binary operator overload resolution An operation of the form x op y, where op is an overloadable binary operator, x is an expression of type X, and y is an expression of type Y, is processed as follows:

This list of public available standards listed here: https://standards.iso.org/ittf/PubliclyAvailableStandards/index.html

Upvotes: 2

Related Questions