C# DateTime always create new object?

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.


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.


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).

Tags:

C#

Datetime