为什么字符串不像引用类型那样?

时间:2014-12-24 08:27:59

标签: c# string

可能是因为它是不可变的。

    class A
    {
        public string a;
    }

    static void Main(string[] args)
    {
        A a1 = new A();
        A b1 = new A();
        string a = "abc";
        a1.a = "abc";
        string b = "ca";
        b1.a = "ca";
        a = b;
        a1 = b1;
        b = "cab";
        b1.a = "cab";
        Console.WriteLine(a);
        Console.WriteLine(a1.a);
        Console.ReadLine();
    }

a1.a的答案是“ca”和a“a”的“cab”,这就是我在面试问题中回答的问题,我将原因解释为字符串的“不变性”。

但面试官并不相信。有人可以提供上述代码的令人信服的解释吗?

5 个答案:

答案 0 :(得分:8)

这种情况对于不变性有 。这完全取决于引用类型的工作原理。

在你的;

a = b;

行,您的ba引用指向同一个对象"ca"并且更改b对另一个对象的引用不会影响{{1分数。

让我试着逐行解释这里发生的事情;

首先,string引用类型,引用类型有2个部分。该对象的对象引用

在你的

a

行,你有一个string a = "abc"; 对象和一个名为"abc"的对象的引用。

a

在这一行中,您有一个string b = "ca"; 对象和一个名为"ca"的对象的引用。

b

在此行中,现在a = b; 引用指向a引用点为b的同一对象。

"ca"

在此行中,您创建了一个名为b = "cab"; 的新对象,而您的"cab"引用现在指向此对象。它不再指向b个对象。

"ca"

在此行中,由于Console.WriteLine(a); 仍然引用a对象,因此将打印此字符串。更改"ca"引用的对象不会影响它。

答案 1 :(得分:1)

没有字符串不变的情况。该字符串是引用类型。最初,您将a设置为指向值为“abc”的字符串。将b设置为指向值为ca的字符串时。之后,您将a设为等于b。由于它们都是引用类型,a现在指向b所指向的位置。换句话说,现在a指向ca。稍后您只需更改b指向的位置。此更改不会影响a指向的值。

答案 2 :(得分:1)

这更多地与C#中指针和引用之间的区别有关。

a = b,你不会指向现在和未来的任何b。您不能将指针变量a分配给指针变量b(C ++指针的行为方式)。

因为它们是引用,所以在当时保存的任何(字符串) b初始化。就是这样,与b的任何其他联系都会丢失。

它就像一个复制构造函数,为a创建了一个新的字符串值。当b再次改变时,a不会受到影响。因为它们拥有不同的物体!

修改

复制过程的更正:实际上没有创建新对象。与指针不同的是在该时间点的对象的内存地址的一次性分配。 a将指向相同的字符串值,在内存中,由b 在该时间点保持并且它是,将来不再与b相关联。

答案 3 :(得分:1)

虽然Sonor的答案很精彩且正确,但却忽略了一个重要的观点。整点都与字符串无关。这个谜题与整数完全相同:

class A
{
    public int a;
}

static void Main(string[] args)
{
    A a1 = new A();
    A b1 = new A();
    int a = 123;
    a1.a = 123;
    int b = 31;
    b1.a = 31;
    a = b;
    a1 = b1;
    b = 312;
    b1.a = 312;
    Console.WriteLine(a);
    Console.WriteLine(a1.a);
    Console.ReadLine();
}

关键事实是a1和b1是参考。 (不是a和b)

答案 4 :(得分:0)

这个问题实际上解决了我对字符串文字的一些误解。

  1. string a="abc";的含义是什么?
  2. 我实际上是将“abc”视为a指向的值。

    但这部分是正确的。

    “abc”是字符串文字,它本身就是一个字符串对象(由ldstr IL指令创建),如下面的链接所示,该语句基本上使a局部变量指向字符串文字

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

    1. 以下代码对我意味着什么?

      string b = "ca";
      a = b;
      b = "cab";
      
    2. 我认为"cab"作为b指向的值的更新,因此a也将更新。 我认为由于字符串的不变性,价值不会得到更新。

      但由于字符串文字不是一个值,而是一个等同于以下代码的对象:(因此给出了我的问题的答案)

      string b = "ca";
      a = b;
      string c = "cab";
      b = c;