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

viv*_*una 6 c# string

string s = "";
for(int i=0;i<10;i++) {
s = s + i;
}
Run Code Online (Sandbox Code Playgroud)

我一直是这些选择来回答这个问题.

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

我有这个简单的代码,我只想知道这个代码将创建多少个字符串对象.

我有一个疑问,是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??
Run Code Online (Sandbox Code Playgroud)

我按照下面的链接,但仍然不清楚.

链接1

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

string str;

string str = null;
Run Code Online (Sandbox Code Playgroud)

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

str = "abc";
Run Code Online (Sandbox Code Playgroud)

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

我尝试了下面的代码,只是为了确定是否创建了新对象.它为每次迭代写"不同".这意味着它总是给我一个不同的对象,所以有可能有10或20个对象.因为它没有给我中间状态的信息(拳击i时做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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

我不同意string str = ""不创建任何对象的声明.我几乎尝试过这个.

    string s = null;
    object obj = null;

    if (Object.ReferenceEquals(s, obj))
    {
        Console.Write("Same");
    }
    else
    {
        Console.Write("Different");
    }
Run Code Online (Sandbox Code Playgroud)

代码写入"相同",但如果我写string s = "";,它在控制台上写"不同".

我现在还有一个疑问.

s = s + i和之间的区别是什么s = 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)
Run Code Online (Sandbox Code Playgroud)

s = s + i IL代码

IL_000e:  box        [mscorlib]System.Int32
IL_0013:  call       string [mscorlib]System.String::Concat(object, object)
Run Code Online (Sandbox Code Playgroud)

所以盒子和实例在这里有什么不同

Dmi*_*nko 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;
}
Run Code Online (Sandbox Code Playgroud)

要测试string s = ""它不会创建一个额外的对象,你可以放

string s = "";

if (object.ReferenceEquals(s, string.Empty))
  Console.Write("Empty string has been cached");
Run Code Online (Sandbox Code Playgroud)

最后,我们20的对象:0 + 10 * 2(10盒装intS和10 stringS).的情况下

string result = "1" + "2" + "3" + "4";
Run Code Online (Sandbox Code Playgroud)

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

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

string str = null; // no objects created
...
str = "abc"; // an object ("abc") created
Run Code Online (Sandbox Code Playgroud)

  • 然后选项是错误的.另外,每次迭代都会加载`i`,这将创建一个额外的*对象*(虽然不是字符串). (6认同)
  • 代码中的字符串文字由JITter在JITting时间实现.是的,创建一个字符串对象来保存空字符串,但它不是由问题*中的代码创建的*.它是在程序开始运行时由运行时创建的.这个代码是否完全没有任何区别,仍然创建了空字符串.因此,由于问题是"通过下面的代码",因此空字符串不计算在内.它不是由代码*创建的*.相反,使用了对现有空字符串的引用,而不是在内存中创建另一个字符串对象. (3认同)
  • @ sr28:是的,`string.Empty`符合这个定义(包含零符号); 因为`string`是*immutable*类,你可以*共享*实例,即不创建它们,而是从缓存中获取 (2认同)