If DateTime is immutable, why does the following work?

前端 未结 6 1458
轻奢々
轻奢々 2021-01-03 20:34

I thought I understood what Immutable meant, however I don\'t understand why the following compiles and works:

DateTime dt = DateTime.Now;

Console.WriteLine         


        
相关标签:
6条回答
  • 2021-01-03 21:25

    If an instance of a non-trivial structure type is stored in a writable storage location (non-readonly field, local variable, array slot, etc.), all of its fields will be mutable. If an instance is stored in a non-writable storage location (a readonly field, a compiler-generated temporary value, etc.), then none of its fields will be mutable. The concept of an "immutable structure type" is a misnomer, since the statement:

    myStruct1 = myStruct2; // Assume variables are of the same structure type
    

    will, if myStruct1 is writable, replace all public and private fields of myStruct1 with the corresponding fields of myStruct2; if myStruct1 isn't writable, the statement will generate a compile-time error. The code for the structure gets no say in the matter, and won't even be notified that the assignment as taken place.

    Although DateTime provides no means by which an existing DateTime instance can be modified except by whole-structure assignment, it can do nothing to prevent code from overwriting the fields of one instance with the contents of another, as happens with dateTimeVariable = DateTime.Now;.

    0 讨论(0)
  • 2021-01-03 21:28

    The DateTime object itself is immutable, but not the reference dt. dt is allowed to change which DateTime object it points to. The immutability refers to the fact we can't change the variables inside a DateTime object.

    For example, we can't go

    dt.Day = 3;
    

    dt itself is just a reference variable that points towards a DateTime object. By its definition, it's allowed to vary.

    As pst mentioned, though, readonly and const are probably closer to what you're thinking, where you can't change the value of a variable.


    Side note: DateTime is a Structure, and therefore, a value type, and I'm being misleading by calling dt a 'reference.' However, I think it still holds true that dt is still just a variable 'pointing' at an immutable object, and the variable itself is still mutable. Thanks to dan04 for pointing that out.

    0 讨论(0)
  • 2021-01-03 21:31

    See this.

    Read the description of all those methods. It always says "Returns a new DateTime...". It does not change the current DateTime object, thus it is immutable.

    Variable reference is a different thing. Think of it just as a pointer to the actual immutable DateTime object that can be changed to point a different one.

    0 讨论(0)
  • 2021-01-03 21:36

    The Now property is something like:

     DateTime Now {
         get {
             // Get the OS time
             return new DateTime(year, month, day, hour, min, sec...)
         }
     }
    

    (technically false, the Now calls internally the UtcNow that calls the OS :-), but you get the idea).

    The DateTime.Now is a factory for DateTime :-)

    0 讨论(0)
  • 2021-01-03 21:37

    You're simply telling the variable dt to refer to a different instance of DateTime. Under the hood, the DateTime.Now property generates a new DateTime instance every time you access it.

    0 讨论(0)
  • 2021-01-03 21:39

    The answer is simple. DateTime is not immutable. It is a struct. And I don't know how it's possible to have an immutable struct.

    If you do this:

    DateTime d1 = DateTime.Now;
    DateTime d2 = DateTime.Now;
    d1 = d2;
    

    Then, the struct d1 will be overwritten with d2's values.

    (A DateTime really only has one value. If you run a decompiler it is a private field called "ticks" I believe.)

    There is no reference stuff going on, or anything else funky.

    0 讨论(0)
提交回复
热议问题