如果所有内置类型在 C# 中都是不可变的,这是否意味着在为它们分配新值后它们的内存位置应该改变?

If all built-in types are immutable in C#, doesn't it mean that after assigning them a new value their memory location should change?

我正在努力理解 C# 中可变和不可变类型的概念,我认为它们不能更改 "in place",只有创建新变量(同名?)并将编辑后的值分配给它。这是否意味着它应该有不同的内存位置?我在 VS2015 中对其进行了试验,但似乎没有...

unsafe
{
    int a = 7;
    int* test = &a;

    Console.WriteLine(a);                
    Console.WriteLine((int)test);
    a+=5;
    test = &a;
    Console.WriteLine(a);
    Console.WriteLine((int)test);
    Console.ReadKey();
}

它输出:

7
107604264
12
107604264

我认为这里的问题是您混淆了变量和值。变量只是可以存储值(对于值类型)或对值的引用(对于引用类型)的位置的名称。出于我们在这里讨论的目的,存储变量 how/where 并不重要,因为我们正在谈论 .

的不变性

当您将值“7”分配给整数变量时,该值“7”将始终为“7”。您无法在代码中做任何事情来使它成为“7”以外的东西。如果它是可变的,那意味着什么?这就像将“7”更改为“12”,然后将程序中以前包含“7”的所有其他变量现在包含“12”。

如果您改为查看不可变引用类型,这会更清楚一些,例如 'string'。如果我设置a = "Test"b = aa = "Test2",b的值仍然是"Test"。通常不可能更改字符串的内容(在不违反不变性的情况下偷偷访问私有内存),因此我们称字符串值是不可变的。您可以相信,一旦将字符串引用存储到变量中,它所引用的字符串值将永远不会改变。

An object is immutable if its state doesn’t change once the object has been created.

它只是关于状态,这就是重点。 IMO mutability/immutability 与类型无关但与实例相关,因此实例是可变的或不可变的。通常,如果您声明类型是不可变的,则意味着该类型的所有实例都是不可变的。混淆可能来自 referencevalue 类型,但通常,两者都可能是可变的或不可变的,尽管强烈建议保持 value 类型不可变。


public class Immutable
{
    public int X {get; private set;}

    public Immutable(int x)
    {
        X = x;
    }
}

public class Mutable
{
    public int X {get; set;}

    public Mutable(int x)
    {
        X = x;
    }
}

实际上没有人阻止您更改不可变对象的引用class它仍然是不可变的,因为您实际上无法更改状态

//the state can be changed Mutable
Mutable m = new Mutable(1);
m.X = 2; 

//the state cannot be changed
Immutable obj1 = new Immutable(1);
Immutable obj2 = new Immutable(2);
obj1 = obj2;