Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[suggestion] Compiler should call ToString on non-string types used with string.operator+ #10966

@jamesqo

Description

@jamesqo

Background

There's a lot of code out there that uses string concatenation to append arbitrary objects to strings, like so:

public class MutablePerson
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override void ToString()
    {
        return this.Name + " is " + this.Age + " years old.";
    }
}

At compile-time, Roslyn tranforms calls to string.operator+ to string.Concat to avoid allocating intermediary strings, so what we end up with is this:

public override void ToString()
{
    return string.Concat(this.Name, " is ", this.Age, " years old.");
}

Unfortunately, string.Concat only accepts object parameters, meaning that Age (which is an int) is implicitly boxed when it is passed into the function. Of course, boxing is no good for performance, so if the developer wants to avoid this, he/she has to explicitly call ToString on the variable, e.g.

return this.Name + " is " + this.Age.ToString() + " years old.";

and the compiler will do the right thing and omit the box instruction.

An example of where this really became a pain was dotnet/corefx#8025, where a bunch of ToString calls had to be added to avoid boxing on each item.

Proposal

Instead of calling the string.Concat overloads that accept objects, the compiler should exclusively generate code targeting the ones accepting a string. For value types, the code generated would coerce the variable into a string via ToString:

"foo" + someStruct + "bar"; // what was written
string.Concat("foo", someStruct.ToString(), "bar"); // what was emitted

Existing strings could simply be concatenated directly, without a ToString call (same behavior as today):

"quux" + someString; // what was written
string.Concat("quux", someString); // what was emitted

And for other reference types, a ToString would be emitted with an extra null check:

"baz" + someClass; // what was written
string.Concat("baz", someClass?.ToString()); // what was emitted

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-CompilersCode Gen QualityRoom for improvement in the quality of the compiler's generated codeFeature - TuplesTuplesFeature Requesthelp wantedThe issue is "up for grabs" - add a comment if you are interested in working on it

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions