Passing a class as a ref parameter in C# does not always work as expected. Can anyone explain?

前端 未结 4 434
慢半拍i
慢半拍i 2020-12-08 14:37

I always thought that a method parameter with a class type is passed as a reference parameter by default. Apparently that is not always the case. Consider these unit tests

4条回答
  •  旧巷少年郎
    2020-12-08 15:06

    The thing that is nearly always forgotten is that a class isn't passed by reference, the reference to the class is passed by value.

    This is important. Instead of copying the entire class (pass by value in the stereotypical sense), the reference to that class (I'm trying to avoid saying "pointer") is copied. This is 4 or 8 bytes; much more palatable than copying the whole class and in effect means the class is passed "by reference".

    At this point, the method has it's own copy of the reference to the class. Assignment to that reference is scoped within the method (the method re-assigned only its own copy of the reference).

    Dereferencing that reference (as in, talking to class members) would work as you'd expect: you'd see the underlying class unless you change it to look at a new instance (which is what you do in your failing test).

    Using the ref keyword is effectively passing the reference itself by reference (pointer to a pointer sort of thing).

    As always, Jon Skeet has provided a very well written overview:

    http://www.yoda.arachsys.com/csharp/parameters.html

    Pay attention to the "Reference parameters" part:

    Reference parameters don't pass the values of the variables used in the function member invocation - they use the variables themselves.

    If the method assigns something to a ref reference, then the caller's copy is also affected (as you have observed) because they are looking at the same reference to an instance in memory (as opposed to each having their own copy).

提交回复
热议问题