字符串对象真的是通过引用?

Ism*_*ael 14 .net c# string reference

我正在学习(新手).NET,我有些疑惑.

从书中读到的例子我了解到String是对象,然后是Reference Type.

所以,我做了这个测试,结果与我的预期不同:

我真的很好奇,这是一个例外,因为"字符串"是特殊类型吗?

class Program
{
    static void Main(string[] args)
    {
        SByte a = 0;
        Byte b = 0;
        Int16 c = 0;
        Int32 d = 0;
        Int64 e = 0;
        string s = "";
        Exception ex = new Exception();

        object[] types = { a, b, c, d, e, s, ex };

        // C#
        foreach (object o in types)
        {
            string type;
            if (o.GetType().IsValueType)
                type = "Value type";
            else
                type = "Reference Type";
            Console.WriteLine("{0}: {1}", o.GetType(), type);
        }

        // Test if change
        string str = "I'll never will change!";

        Program.changeMe(str);

        Console.WriteLine(str);
    }

    public static string changeMe(string param)
    {
        param = "I have changed you!!!";

        return ""; // no return for test
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

System.SByte: Value type
System.Byte: Value type
System.Int16: Value type
System.Int32: Value type
System.Int64: Value type
System.String: Reference Type
System.Exception: Reference Type
I'll never will change!
Run Code Online (Sandbox Code Playgroud)

ito*_*son 20

String确实是一种引用类型.但是,当您的Main方法调用changeMe(str)时,.NET会在param参数中将str的引用副本传递给changeMe.然后,changeMe修改此副本以引用"我已经改变了你!!!",但原始的str引用仍然指向"我永远不会改变".

作为引用类型意味着如果您更改了传递的字符串的状态,则调用者将看到这些更改.(你不能对字符串执行此操作,因为字符串是不可变的,但您可以将其用于其他引用类型,例如Control.)但是重新分配参数不会更改调用者在该参数中传递的,即使该值是一个参考.


Fra*_*ger 13

字符串是参考.

changeMe 不会更改字符串,它只是在该函数中重新分配本地引用(指针).

现在,如果您将字符串作为refarg 传递,您可以获得更多乐趣:

public static string changeMe(ref string param) {
    param = "I have changed you!!!";
    return ""; // no return for test
}
Run Code Online (Sandbox Code Playgroud)