下面的代码创建了多少个字符串对象?

时间:2016-11-10 09:50:49

标签: c# string

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

我一直有这些选择来回答这个问题。

  1. 1
  2. 11
  3. 10
  4. 2
  5. 我有这个简单的代码,我只想知道这个代码将创建多少个字符串对象。

    我有一个疑问,是string s = "";没有创造任何对象。我不这么认为,请让我说清楚。

    如果我用+运算符追加字符串,它会创建新的字符串,所以我认为它将是在for循环的每次迭代中创建的新对象。

    所以我认为会创建11个对象。让我知道如果我不对。

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

    我按照以下链接,但仍然不清楚。

    Link1

    请同时涵盖string strstring str = null案例。如果我们不初始化字符串以及何时将字符串赋值为null,会发生什么。所以在这两种情况下它将是一个对象或没有对象。

    string str;
    
    string str = null;
    

    稍后在代码中,如果我这样做。

    str = "abc";
    

    有没有任何编程方式来计算对象的数量?,因为我认为这可能是一个有争议的话题。如何通过编程或某些工具100%?我在IL代码中看不到这一点。

    我尝试了下面的代码,只是为了确定是否创建了新对象。它写了不同的&#39;对于每次迭代。这意味着它总是给我一个不同的对象,所以有可能有10或20个对象。因为它没有给我中间状态的信息(is = 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");
            }
        }
    

    我不同意string str = ""没有创建任何对象的声明。我几乎试过了。

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

    代码写入&#34;相同&#34;,但是如果我写string s = "";,它写&#34;不同&#34;在控制台上。

    我现在还有一个疑问。

    s = s + is = s + i.ToString()之间有什么区别。

    s = s + i.ToString() IL代码

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

    s = s + i IL代码

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

    所以盒子和实例之间的区别是什么

2 个答案:

答案 0 :(得分:6)

好吧,让我们算一下:

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

要测试string s = ""是否创建了其他对象,您可以将其放入

string s = "";

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

最后,我们有20个对象:0 + 10 * 210盒装int10 string s)。在

的情况下
string result = "1" + "2" + "3" + "4";

正如您所看到的,result可以和(将)在编译时计算,因此只会创建一个对象("1234")。在

的情况下
string str; // just a declaration, str contains trash

string str = null; // no objects created
...
str = "abc"; // an object ("abc") created

答案 1 :(得分:0)

尽管德米特里·拜琴科的回答是正确的并得到了很好的解释,但我想补充一些内容。

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

代码将为您提供20个对象。不会为string str = ""创建任何对象,因为引用将缓存空字符串。并且s = s + i;将被用于以下IL代码,因此它保证拳击将发生并且将创建新对象以引用新字符串s + i

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

您可以使用IL Disassembler来查看IL代码。