这里有两个不同的概念在起作用。第一个是DateTime
值类型(又名结构),而Person
[大概]是引用类型(类)。因此,当您这样做时:
DateTime date1 = DateTime.Now;
DateTime date2 = date1;
date2
将导致复制值,因此两个变量不会引用同一个对象。
有了课程,当你这样做时:
Person p1 = new Person();
Person p2 = p1;
p1
实际上不包含 a Person
,它只包含对 person 的引用。然后将该引用(按值)复制到p2
. 复制该引用的效果是两个变量现在都“指向”或“引用”同一个对象。
接下来是可变性的问题。 Person
,在这种情况下,是一个可变类型。这意味着它可以改变。另一方面,不可变类型一旦构造就不能更改。
该行:
p2.Age = 2;
实际上是在更改p2
引用的对象,并且由于p2
两者p1
都引用同一个对象,p1.Age
因此将2
在该行代码之后。
现在,出于演示目的,让我们创建一个不可变Person
类:
public class Person
{
private int _age;
public Person(int someAge)
{
_age = someAge;
}
public int Age
{
get { return _age; }
}
public Person Grow()
{
return new Person(_age + 1);
}
}
如果我们这样做:
Person p1 = new Person(1);
Person p2 = p1;
p2 = p2.Grow();
第二行和以前一样,确保两者都指向同一个对象,但第三行不同。Grow
我们的方法不是更改(或变异)那个人以使其比他大一岁,而是返回一个代表比他大一岁的人的新Person
对象。这样做之后p2
,p1
将不再引用同一个对象;我刚刚将对象p2
引用更改为该Grow
方法刚刚创建的新对象。
第二个示例与正在发生的事情非常相似DateTime
。你不能改变一个DateTime
对象;它是不可变的。调用它的方法(在这种情况下是加号和减号运算符)返回一个全新的对象。按照惯例,值类型不应该在没有令人信服的理由的情况下是可变的,因为处理它们通常很棘手。引用类型可以是不可变的,也可以是可变的;两者都没有重大问题(在一般情况下)。