证明字符串是 C# 中的引用类型

Posted

技术标签:

【中文标题】证明字符串是 C# 中的引用类型【英文标题】:Prove String is referene type in C# 【发布时间】:2014-10-08 03:07:41 【问题描述】:

虽然我知道字符串是引用类型,但我现在可以证明它。因为如果我将变量 test1 作为字符串并分配一些值,然后将其他变量命名为 test2 并将 test2 分配给 test1 变量。因此,如果字符串是引用类型,则变量 test1 的地址将分配给变量 test2。因此,如果我在 tet2 变量中分配了一些值,该值将反映在变量 test1 中,但这并没有发生。

另外一个例子是如果我们在函数中传递两个字符串变量并且在这个函数中改变值将反映在调用函数中,但它不会发生,请参见示例:- 并举个例子,我可以证明字符串是引用类型。但是 case 类对象和字符串变量的行为不同,请再次查看此示例。我已经编辑了

private void button1_Click(object sender, EventArgs e)
    
        string test1 = string.Empty;
        string test2;

        String test3 = new String(new char[10]);

        test1 = "hemant";
        test2 = test1;


        test2 = "Soni";

        //becuase if string is reference type then after asign value "soni"
        // in test2, test1 also show value "soni" instead of value "hemant"

        Console.WriteLine("test1:" + test1); // but displaying "hemant", while shoul display "soni"
        Console.WriteLine("test2:" + test2); // while displaying "soni"

        test3 = "soni";

        // if string is reference type then after calling this function
        //value of variables test1 and test3 should be changed.
        testfn(test1, test3);
        Console.WriteLine("test1:" + test1);// but stile displaying "hemant" instead of "hemant New"
        Console.WriteLine("test3:" + test3);// but stile displaying "soni" instead of "soni New"

        // should be true, because if string reference type then address of both variable should be same.
        bool check = test1 == test2;

        clsTest obj = new clsTest();
        obj.x1 = "Hemant";
        obj.x2 = "Soni";

        Console.WriteLine("obj.x1:" + obj.x1); //"Hemant";
        Console.WriteLine("obj.x2:" + obj.x2);//"Soni";
        callFn(obj);
        //after calling  value has been changed of this object, but in string type its not happed like this
        Console.WriteLine("obj.x1:" + obj.x1); //"Hemant New";
        Console.WriteLine("obj.x2:" + obj.x2);//"Soni New";

        
    
     public class clsTest
    
        public string x1;
        public string x2;
    

    void callFn(clsTest obj)
    
        obj.x1 = "Hemant New";
        obj.x2 = "Soni New";
    
    void testfn(string x, String y)
    
        x = "Hemant New";
        y = "Soni New";
    

【问题讨论】:

您混淆了引用分配和变异。 String 是不可变的。 而且字符串也可以被保留,这在某些情况下可能会增加混乱。 【参考方案1】:

String 是一种引用类型,但它也是不可变的。这意味着,您不能更改字符串对象的值,只能将其替换为对另一个字符串的引用。因此,当您将字符串传递给函数并分配参数时,您只是更改了x 参数的引用,而不是更改 x 处的值。要更改x 的引用,您必须在参数上使用 ref 或 out 关键字。这也适用于 C# 中的任何类型的对象。

class Example 
    public string Value;


void Foo(Example x, ref Example y) 
  x.Value = "mutated"; // mutating the reference
  x = new Example  Value = "new reference" ; // only changes local variable

  y.Value = "mutated"; // mutating the reference
  y = new Example  Value = "new reference" ; // changes the references y is pointing to



var x = new Example  Value = "x" ;
var y = new Example  Value = "y" ;
Foo(x, ref y);

Console.WriteLine(x.Value); // mutated
Console.WriteLine(y.Value); // new reference

但是由于字符串是不可变的(它不能被变异),唯一改变作为参数传入的值的方法是使用 ref 或 out 关键字。

【讨论】:

但是在两种情况下,类对象和字符串变量的行为是不同的,请参见示例: 但是case类对象和字符串的行为是不同的,请看上面的例子,我用类对象编辑过 是的,这就是我所说的,因为您正在改变对象引用指向的值。但是你不能对字符串这样做。简单地更改引用不会更改值。例如,将函数更改为此并重试:void callFn(clsTest obj) obj = new clsTest x1 = "new", x2 = "new" ; 您会注意到在这种情况下它现在不会更改值。现在对于 sting 情况,试试这个:testFn(string x, string y) x[0] = 'n'; x[1] = 'e'; x[2] = 'w'; 这会改变字符串,但请注意这是不允许的,会导致编译器错误。【参考方案2】:

ref 关键字添加到 testfn。

void testfn(ref string x, ref String y)

这将直接引用对象。

MSDN ref page

【讨论】:

以上是关于证明字符串是 C# 中的引用类型的主要内容,如果未能解决你的问题,请参考以下文章

C#字符串引用类型?

c#中的引用类型和值类型有啥区别?

c#中值类型和引用类型的区别

C#详解值类型和引用类型区别

C#中的引用传递值传递

字符串是值类型还是引用类型?