Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
267 views
in Technique[技术] by (71.8m points)

c# - How many String objects will be created when using a plus sign?

How many String objects will be created when using a plus sign in the below code?

String result = "1" + "2" + "3" + "4";

If it was as below, I would have said three String objects: "1", "2", "12".

String result = "1" + "2";

I also know that String objects are cached in the String Intern Pool/Table for performance improvement, but that's not the question.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Surprisingly, it depends.

If you do this in a method:

void Foo() {
    String one = "1";
    String two = "2";
    String result = one + two + "34";
    Console.Out.WriteLine(result);
}

then the compiler seems to emit the code using String.Concat as @Joachim answered (+1 to him btw).

If you define them as constants, e.g.:

const String one = "1";
const String two = "2";
const String result = one + two + "34";

or as literals, as in the original question:

String result = "1" + "2" + "3" + "4";

then the compiler will optimize away those + signs. It's equivalent to:

const String result = "1234";

Furthermore, the compiler will remove extraneous constant expressions, and only emit them if they are used or exposed. For instance, this program:

const String one = "1";
const String two = "1";
const String result = one + two + "34";

public static void main(string[] args) {
    Console.Out.WriteLine(result);
}

Only generates one string- the constant result (equal to "1234"). one and two do not show up in the resulting IL.

Keep in mind that there may be further optimizations at runtime. I'm just going by what IL is produced.

Finally, as regards interning, constants and literals are interned, but the value which is interned is the resulting constant value in the IL, not the literal. This means that you might get even fewer string objects than you expect, since multiple identically-defined constants or literals will actually be the same object! This is illustrated by the following:

public class Program
{
    private const String one = "1";
    private const String two = "2";
    private const String RESULT = one + two + "34";

    static String MakeIt()
    {
        return "1" + "2" + "3" + "4";
    }   

    static void Main(string[] args)
    {
        string result = "1" + "2" + "34";

        // Prints "True"
        Console.Out.WriteLine(Object.ReferenceEquals(result, MakeIt()));

        // Prints "True" also
        Console.Out.WriteLine(Object.ReferenceEquals(result, RESULT));
        Console.ReadKey();
    }
}

In the case where Strings are concatenated in a loop (or otherwise dynamically), you end up with one extra string per concatenation. For instance, the following creates 12 string instances: 2 constants + 10 iterations, each resulting in a new String instance:

public class Program
{
    static void Main(string[] args)
    {
        string result = "";
        for (int i = 0; i < 10; i++)
            result += "a";
        Console.ReadKey();
    }
}

But (also surprisingly), multiple consecutive concatenations are combined by the compiler into a single multi-string concatenation. For example, this program also only produces 12 string instances! This is because "Even if you use several + operators in one statement, the string content is copied only once."

public class Program
{
    static void Main(string[] args)
    {
        string result = "";
        for (int i = 0; i < 10; i++)
            result += "a" + result;
        Console.ReadKey();
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...