19

why in C# my two variables points to different DateTime objects?

DateTime a1 = DateTime.Now;
DateTime a2 = a1;

a1 = a1 + TimeSpan.FromMinutes(15);
a2 = a2 - TimeSpan.FromMinutes(16);

I realized that a2 actually points to a new object which is different from a1.

But In other case. Say i have a class Person, and age = 1;

Person a1 = new Person();
a2 = a1;
a2 = Person.Age = 2;

In the Person Case, a1 and a2 are pointing to same object. I am really confused here, anyone can explain?

retide
  • 1,170
  • 1
  • 13
  • 31

4 Answers4

41

DateTime is a value type - a structure.

With value types, when you do something like:

DateTime a2 = a1;

a2 gets a copy of the values of a1. It is not the same reference to the same memory location, but a complete, separate copy.

On the other hand, Person is a reference type - a class.

When you do:

Person p2 = p1;

With a reference type, the reference that p2 points to is the same one that p1 points to. So changes in one are changes to both.

See Value Types and Reference Types on MSDN.

John Cummings
  • 1,949
  • 3
  • 22
  • 38
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • DateTime is immutable if i'm not wrong. I'm actually in a confusion. String in Immutable also but that is reference type. I want to ask is it not effect for a Immutability that what type is actually? I will appreciate your answer thanks. – Nomi Ali Dec 30 '13 at 17:26
  • 2
    @NomiAli - why not post a question then? Value types are normally created as immutable (and it fits their semantics quite well). `string` was created as immutable for many different reasons (optimization is one). You can create immutable value or reference types. – Oded Dec 30 '13 at 17:40
8

As others have already pointed out DateTime is a struct, not a class and therefore a value type. You can visualize this in the Visual Studio editor, if you change the text color used to display structs. Open the dialog in menu Tools > Options and navigate to Environment > Fonts and Colors

enter image description here

It is helpful to change the color of delegates, enums, interfaces and structs (Value types).

enter image description here

In Visual Studio 2019, you can also change the look of User Members like constants or parameters.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
4

There are two separate concepts at work here. The first is that DateTime is a value type (a.k.a. a struct) while Person is [presumably] a reference type (a class). Because of this, when you do:

DateTime date1 = DateTime.Now;
DateTime date2 = date1;

date2 will result in copying the value, so the two variables will not reference the same object.

With classes, when you do:

Person p1 = new Person();
Person p2 = p1;

p1 doesn't actually contain a Person, it just contains a reference to a person. That reference is then copied (by value) to p2. The effect of copying that reference is that both variables are now "pointing to" or "referencing" the same object.

Next there is the issue of mutability. Person, in this case, is a mutable type. That means that it can be changed. An immutble type on the other hand cannot be changed once constructed.

The line:

p2.Age = 2;

is actually changing the object that p2 references, and since p2 and p1 both reference the same object, p1.Age would be 2 after that line of code.

Now, for demonstration purposes, let's make an immutable Person class:

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);
    }
}

If we do something like this:

Person p1 = new Person(1);
Person p2 = p1;
p2 = p2.Grow();

the second line is doing just what it was before, ensuring that both point to the same object, but the third line is different. Rather than changing (or mutating) that person to make it a year older, our Grow method returns a new Person object that represents someone a year older. After doing this p2 and p1 will no longer be referencing the same object; I have just changed what object p2 references to a new one that the Grow method just created.

This second example is rather similar to what's going on with DateTime. You can't mutate a DateTime object; it is immutable. Calling it's methods (in this case the plus and minus operators) returns and entirely new object. By convention, value types shouldn't be mutable without some compelling reason, as it can often be tricky to deal with them. Reference types can be either immutable or mutable; neither has significant problems (in the general case).

Servy
  • 202,030
  • 26
  • 332
  • 449
3

The difference here is that DateTime is a value type, and I'm assuming that Person is a reference type (class).

In the case of a variable assignment of a value type, you are actually copying the contents of memory from one location to another.

However, in the case of a reference type, you're still pointing at the same piece of memory.

RQDQ
  • 15,461
  • 2
  • 32
  • 59