6
string s = "";
for(int i=0;i<10;i++) {
s = s + i;
}

I have been these options to answer this question.

  1. 1
  2. 11
  3. 10
  4. 2

I have this simple code, I just want to know how many string objects will be created by this code.

I have a doubt, Is string s = ""; creates no object. I dont think so, Please make me clear.

If I append string with + operator, it creates new string, so I think It will be a new object created in every iteration of for loop.

So I think there will be 11 objects created. Let me know If I'm incorrect.

String result = "1" + "2" + "3" + "4";  //Compiler will optimise this code to the below line.
String result = "1234"; //So in this case only 1 object will be created??

I followed the below link, but still its not clear.

Link1

Please cover string str and string str = null case too. What happens If we dont initialize string and when If I assign string to null. So It will be an object or no object in these two cases.

string str;

string str = null;

Later in the code, If I do.

str = "abc";

Is there any programming way to calculate number of objects?, because I think It may by a debatable topic. How can I be 100 % by doing some programming or by some tool? I cannot see this in IL code.

I have tried the below code,just to make sure whether new object is created or not. It writes 'different' for each iteration. It means it always gives me a different object, So there can a possibility of 10 or 20 objects. because it does not give me info of intermediate state(boxing for i when doing s = s + i)

    string s = "0";
    object obj = s;
    for (int i = 0; i < 10; i++)
    {
        s = s + i;

        if (Object.ReferenceEquals(s, obj))
        {
            Console.Write("Same");
        }
        else
        {
            Console.Write("Different");
        }
    }

I'm not agreed by the statement that string str = "" does not create any object. I tried this practically.

    string s = null;
    object obj = null;

    if (Object.ReferenceEquals(s, obj))
    {
        Console.Write("Same");
    }
    else
    {
        Console.Write("Different");
    }

Code writes "Same", but If I write string s = "";, It writes "Different" on console.

I have one more doubt now.

what is difference between s = s + i and s = s + i.ToString().

s = s + i.ToString() IL Code

IL_000f:  call       instance string [mscorlib]System.Int32::ToString()
IL_0014:  call       string [mscorlib]System.String::Concat(string, string)

s = s + i IL Code

IL_000e:  box        [mscorlib]System.Int32
IL_0013:  call       string [mscorlib]System.String::Concat(object, object)

So Whats difference between box and instance here

5
  • 1
    Try ReferenceEquals("", string.Empty). string s = null; doesn't store a reference to a string, it stores a null reference, whereas string s = ""; stores a reference to the existing empty string object, no new object was created for that statement. Commented Nov 10, 2016 at 10:25
  • 1
    To your last update. Since string is immutable class you can share the instances (i.e. cache them), but, sure, don't have to do it. Empty string is very popular instance, that's why it's cached explictly as string.Empty. string s = "0"; is not that frequent and .Net doesn't cache it as a special case. Commented Nov 10, 2016 at 10:25
  • 1
    Also try this: string s1 = "test"; string s2 = "test"; ReferenceEquals(s1, s2), the last expression will return true since string literals are interned and reused by the JITter. Only 1 new string object was created because of this code, a single string object holding the text "test". Commented Nov 10, 2016 at 10:26
  • int is a struct, which passes by value, object passes by reference; boxing creates a wrapping object over struct int (similar to Integer and int in Java) see stackoverflow.com/questions/2111857/…; i.ToString() is just a method Commented Nov 10, 2016 at 14:03
  • is wrapping object means creating new object? So when I change from value type to reference type, does new object get created ? Commented Nov 10, 2016 at 14:06

2 Answers 2

6

Well, let's count:

string s = ""; // no new objects created, s assigned to string.Empty from the cache

// 10 times:
for(int i = 0; i < 10; i++) {
  // i     <- first object to create (boxing): (object) i
  // s + i <- second object to create: string.Concat(s, (object) i);
  s = s + i;
}

To test that string s = "" doesn't create an additional object you can put

string s = "";

if (object.ReferenceEquals(s, string.Empty))
  Console.Write("Empty string has been cached");

finally, we have 20 objects: 0 + 10 * 2 (10 boxed ints and 10 strings). In case of

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

as you can see the result can be and (will be) computed at the compile time, so just one object ("1234") will be created. In case of

string str; // just a declaration, str contains trash

string str = null; // no objects created
...
str = "abc"; // an object ("abc") created
Sign up to request clarification or add additional context in comments.

18 Comments

Then the options are wrong. Additionally, i will be boxed for each iteration which will create an additional object (not a string though).
@sr28: "" is cached as string.Empty; you can convince youself by if (Object.ReferenceEquals(s, string.Empty)) Console.Write("cached");
@sr28: yes, and string.Empty fits this definition (contains zero symbols); since string is immutable class, you can share the instances, i.e. don't create them but take from cache
String literals in code are interned by the JITter at JITting time. Yes, a string object is created to hold the empty string, but it isn't created by the code in the question. It was created way earlier when the program started running, by the runtime. Whether this code was present at all makes no difference, the empty string was still created. As such, since the question ask "by below code", then the empty string doesn't count. It wasn't created by that code. Instead, a reference to the existing empty string was used instead which did not create another string object in memory.
Lasse V. Karlsen is right. Strings are cached. When you create a string which has the same content than another string that already exists you only have 1 object(2 references to that 1 object). This works because string is immutable which means you can not change it. Whenever you try to change it you create a new instance (or reference another if an already existing string equals another yours after change)
|
0

Although Dmitry Bychenko answer is right and well explained, But I want to add something.

string s = "";
for(int i=0;i<10;i++) {
s = s + i;
}

Code will give you 20 objects. No object will be created for string str = "", because reference will have cached empty string. And s = s + i; will be expended to the following IL code, So its giving guaranty that boxing will happen and new object will be created to refer new string s + i

IL_000e:  box        [mscorlib]System.Int32
IL_0013:  call       string [mscorlib]System.String::Concat(object, object)

You can see IL code by using IL Disassembler.

3 Comments

Note that s=s+i.ToString(); generates different code to s=s+i; and does create a new string - so the answer to your original question should be 10 String objects are created (along with 10 boxed ints). If you used s=s+i.ToString() then 20 string objects are created.
@PaulF so you mean when I do s = s+ i, only boxing happens but it does not create new opbject. When we do i.ToString it creates new object??
What happens with s=s+i is that a new boxed int object is created & this is concatenated with the original string - internally a new string object maybe created from the boxed int - but I would consider that the same way that creation of the empty string has been (ie ignored). In the case of s=s+i.ToString(); then a new string object is explicitly created & the two strings concatenated. I have always considered s=s+i as just a short-hand for s=s+i.ToString() - so I was surprised to see completely different code generated.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.