为什么在C#中我的两个变量指向不同的DateTime对象?
DateTime a1 = DateTime.Now;
DateTime a2 = a1;
a1 = a1 + TimeSpan.FromMinutes(15);
a2 = a2 - TimeSpan.FromMinutes(16);
我意识到a2实际上指的是一个与a1不同的新对象。
但在其他情况下。假设我有一个人类,年龄= 1;
Person a1 = new Person();
a2 = a1;
a2 = Person.Age = 2;
在Person Case中,a1和a2指向同一个对象。我真的很困惑,有人可以解释一下吗?
答案 0 :(得分:27)
DateTime
是一种值类型 - 结构。
使用值类型时,执行以下操作:
DateTime a2 = a1;
a2
获取a1
值的副本。它与同一个内存位置不同,只是一个完整的单独副本。
另一方面,Person
是一个引用类型 - 一个类。
当你这样做时:
Person p2 = p1;
使用引用类型时,p2
指向的引用与p1
指向的引用相同。因此,一方面的变化都是两者的变化。
请参阅MSDN上的Value Types and Reference Types。
答案 1 :(得分:7)
正如其他人已经指出的那样DateTime
是一个结构,而不是一个类,因此是一个值类型。如果更改用于显示结构的文本颜色,则可以在Visual Studio编辑器中将其可视化。在菜单Tools
>中打开对话框Options
并导航至Environment
> Fonts and Colors
更改委托,枚举,接口和结构(值类型)的颜色会很有帮助。
答案 2 :(得分:3)
这里的区别是DateTime是一个值类型,我假设Person是一个引用类型(类)。
对于值类型的变量赋值,实际上是将内存的内容从一个位置复制到另一个位置。
但是,在引用类型的情况下,您仍然指向同一块内存。
答案 3 :(得分:3)
这里有两个独立的概念。第一个是DateTime
是一个值类型(a.k.a。一个结构),而Person
是[推测]是一个引用类型(一个类)。因此,当你这样做时:
DateTime date1 = DateTime.Now;
DateTime date2 = date1;
date2
将导致复制值,因此这两个变量不会引用同一个对象。
使用课程时:
Person p1 = new Person();
Person p2 = p1;
p1
实际上并不包含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
对象;它是不可改变的。调用它的方法(在这种情况下是加号和减号运算符)返回并且是全新的对象。按照惯例,价值类型在没有一些令人信服的理由的情况下不应该是可变的,因为处理它们通常很棘手。引用类型可以是不可变的,也可以是可变的;没有重大问题(在一般情况下)。