这里有两个不同的概念在起作用。第一个是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对象;它是不可变的。调用它的方法(在这种情况下是加号和减号运算符)返回一个全新的对象。按照惯例,值类型不应该在没有令人信服的理由的情况下是可变的,因为处理它们通常很棘手。引用类型可以是不可变的,也可以是可变的;两者都没有重大问题(在一般情况下)。