Why don't we use new operator while initializing a string?

前端 未结 7 902
太阳男子
太阳男子 2020-12-13 06:05

I was asked this question in an interview: Is string a reference type or a value type.

I said its a reference type. Then he asked me why don\'t we use new operator

7条回答
  •  独厮守ぢ
    2020-12-13 07:02

    Nope. The compiler does not change the construction. What type should the constructor argument be? String? ;-)

    String literals are constants without a name.

    In addition, you can initialize any class with a string literal, if it supports an operator:

       public class UnitTest1 {
          class MyStringable {
             public static implicit operator MyStringable(string value) {
                return new MyStringable();
             }
          }
    
          [TestMethod]
          public void MyTestMethod() {
             MyStringable foo = "abc";
          }
       }
    


    Edit To be more clear: As you asked, if string will be converted into any constructor call, let's have a look into the IL code.

    Taken this test method:

       [TestClass]
       class MyClass {
          [TestMethod]
          public void MyTest() {
             string myString = "foo";
             if (myString == "bar")
                Console.WriteLine("w00t");
          }
       }
    

    Creates the following IL code:

    .method public hidebysig instance void MyTest() cil managed
    {
        .custom instance void [Microsoft.VisualStudio.QualityTools.UnitTestFramework]Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute::.ctor()
        .maxstack 2
        .locals init (
            [0] string myString,
            [1] bool CS$4$0000)
        L_0000: nop 
        L_0001: ldstr "foo"
        L_0006: stloc.0 
        L_0007: ldloc.0 
        L_0008: ldstr "bar"
        L_000d: call bool [mscorlib]System.String::op_Equality(string, string)
        L_0012: ldc.i4.0 
        L_0013: ceq 
        L_0015: stloc.1 
        L_0016: ldloc.1 
        L_0017: brtrue.s L_0024
        L_0019: ldstr "w00t"
        L_001e: call void [mscorlib]System.Console::WriteLine(string)
        L_0023: nop 
        L_0024: ret 
    }
    

    As you see, all string values (foo, bar and w00t) are still strings and do not call any hidden constructor.

    Hope this is more explaining.

提交回复
热议问题