What is the difference between a reference type and value type in c#?

后端 未结 14 2449
谎友^
谎友^ 2020-11-21 05:13

Some guy asked me this question couple of months ago and I couldn\'t explain it in detail. What is the difference between a reference type and a value type in C#?

I

14条回答
  •  时光说笑
    2020-11-21 05:57

    This is from a post of mine from a different forum, about two years ago. While the language is vb.net (as opposed to C#), the Value Type vs. Reference type concepts are uniform throughout .net, and the examples still hold.

    It is also important to remember that within .net, ALL types technically derive from the base type Object. The value types are designed to behave as such, but in the end they also inherit the functionality of base type Object.

    A. Value Types are just that- they represent a distinct area in memory where a discrete VALUE is stored. Value types are of fixed memory size and are stored in the stack, which is a collection of addresses of fixed size.

    When you make a statement like such:

    Dim A as Integer
    DIm B as Integer
    
    A = 3
    B = A 
    

    You have done the following:

    1. Created 2 spaces in memory sufficient to hold 32 bit integer values.
    2. Placed a value of 3 in the memory allocation assigned to A
    3. Placed a value of 3 in the memory allocation assigned to B by assigning it the same value as the held in A.

    The Value of each variable exists discretely in each memory location.

    B. Reference Types can be of various sizes. Therefore, they can't be stored in the "Stack" (remember, the stack is a collection of memory allocations of fixed size?). They are stored in the "Managed Heap". Pointers (or "references") to each item on the managed heap are maintained in the stack (Like an Address). Your code uses these pointers in the stack to access objects stored in the managed heap. So when your code uses a reference variable, it is actually using a pointer (or "address" to an memory location in the managed heap).

    Say you have created a Class named clsPerson, with a string Property Person.Name

    In this case, when you make a statement such as this:

    Dim p1 As clsPerson
    p1 = New clsPerson
    p1.Name = "Jim Morrison"
    
    Dim p2 As Person
    
    p2 = p1
    

    In the case above, the p1.Name Property will Return "Jim Morrison", as you would expect. The p2.Name property will ALSO return "Jim Morrison", as you would Iintuitively expect. I believe that both p1 and p2 represent distinct addresses on the Stack. However, now that you have assigned p2 the value of p1, both p1 and p2 point to the SAME LOCATION on the managed heap.

    Now COnsider THIS situation:

    Dim p1 As clsPerson
    Dim p2 As clsPerson
    
    p1 = New clsPerson
    p1.Name = "Jim Morrison"
    
    p2 = p1
    
    p2.Name = "Janis Joplin"
    

    In this situation, You have created one new instance of the person Class on the Managed Heap with a pointer p1 on the Stack which references the object, and assigned the Name Property of the object instance a value of "Jim Morrison" again. Next, you created another pointer p2 in the Stack, and pointed it at the same address on the managed heap as that referenced by p1 (when you made the assignement p2 = p1).

    Here comes the twist. When you the Assign the Name property of p2 the value "Janis Joplin" you are changing the Name property for the object REFERENCED by Both p1 and p2, such that, if you ran the following code:

    MsgBox(P1.Name)
    'Will return "Janis Joplin"
    
    MsgBox(p2.Name)
    'will ALSO return "Janis Joplin"Because both variables (Pointers on the Stack) reference the SAME OBJECT in memory (an Address on the Managed Heap). 
    

    Did that make sense?

    Last. If you do THIS:

    DIm p1 As New clsPerson
    Dim p2 As New clsPerson
    
    p1.Name = "Jim Morrison"
    p2.Name = "Janis Joplin"
    

    You now have two distinct Person Objects. However, the minute you do THIS again:

    p2 = p1
    

    You have now pointed both back to "Jim Morrison". (I am not exactly sure what happened to the Object on the Heap referenced by p2 . . . I THINK it has now gone out of scope. This is one of those areas where hopefullly someone can set me straight . . .). -EDIT: I BELIEVE this is why you would Set p2 = Nothing OR p2 = New clsPerson before making the new assignment.

    Once again, if you now do THIS:

    p2.Name = "Jimi Hendrix"
    
    MsgBox(p1.Name)
    MsgBox(p2.Name)
    

    Both msgBoxes will now return "Jimi Hendrix"

    This can be pretty confusing for a bit, and I will say one last time, I may have some of the details wrong.

    Good Luck, and hopefully others who know better than me will come along to help clarify some of this . . .

提交回复
热议问题