开发者

C# constructor, object parameter is passed by reference or value

If you have class and a constructor which takes in an object as a input par开发者_开发知识库am - is that object passed by reference or is it passed by value?

And is it true to assume that for class methods, object input parameters are passed by value by default unless the ref keyword is used?

What about the out keyword? Does this still mean that it is passed by reference?


If you have class and a constructor which takes in an object as a input param - is that object passed by reference or is it passed by value?

All parameters are passed by value in C# unless the parameter is marked with out or ref.

This is a huge source of confusion. I'll state things a little more explicitly.

All parameters have their value copied unless the parameter is marked with out or ref. For value types, this means that a copy of the value being passed is made. For reference types this means that a copy of the reference is made. For this last point, the value of a reference type is the reference.

And is it true to assume that for class methods, object input parameters are passed by value by default unless the ref keyword is used?

Again, all parameters are passed by value in C# unless the parameter is marked with out or ref. For a parameter marked with ref, a reference to the parameter is passed to the method and now you can think of that parameter as an alias. Thus, when you say

void M(ref int m) { m = 10; }

int n = 123;
M(ref n);

you can think of m in M as an alias for n. That is m and n are just two different names for the same storage location.

This is very different from

string s = "Hello, world!";
string t = s;

In this case, s and t are not alises for the same storage location. These are two different variables that happen to refer to the same object.

What about the `out keyword? Does this still mean that it is passed by reference?

The only difference between ref and out is that ref requires the variable to be initialized before being passed.


The reference to the object will be passed by value.

.NET has reference types and value types - classes are all reference types and structs are value types. You can pass either one by value or by reference.

By default, everything is passed by value, the difference being that with reference types the reference is passed in.

The ref and out keywords will cause the parameters to be passed by reference - in the case of value types that means you can now make changes that will be reflected in the passed in object. With reference types that means you can now change the object that the reference refers to.


An object is always passed by reference to the actual object. So no copy (aka "by value") is being performed of the object.

Just, as Oded notes, the reference to the object is being copied.


The default passing mechanism for parameters in .Net is by value. This is true for both reference and value types. In the reference case though it's the actual reference which is passed by value, not the object.

When the ref or out keyword is used then the value is indeed passed by reference (once again true for both value and reference types). At a CLR level there is actually no difference between ref and out. The out keyword is a C# notion which is expressed by marking a ref param (I believe it's done with a modopt)


An important thing to understand with reference types is that almost anything one does with a variable of reference type is implicitly done to the thing being referred to by the reference, not to the reference itself. I find it helpful to think of reference types as instance ID's. To use an analogy, think of instances as cars, and reference types as slips of paper with automotive vehicle identification numbers (VINs) written on them. If I copy a VIN onto a slip of paper, hand it to someone in the shop, and say "paint this blue", what I really mean is "find the car with this VIN and paint it blue", not "paint this slip of paper blue". What I'm handing the person is not a car, but merely a VIN; what I'm telling him to paint blue, however, is the car that's sitting in the shop, and not the piece of paper (nor anything else) that I'm actually handing him. Such usage would be passing by value.

Suppose, however, what I wanted was for someone to buy a car and give me the VIN. I might write out on some slip of papers the make, model, color, etc. that I want, and also hand the person a slip of paper on which to write the VIN. In that case, I would want to get back the slip of paper with the new VIN on it. Such usage would be passing the VIN by reference, since the person would be writing the VIN on a piece of paper I supplied and giving it back to me.


@Supercat: It is rather interesting. Perhaps the confusion lies in understanding why you would want to pass a reference type by reference!

Extending the analogy for ref types only ( I think value types are easier to understand)

One may write out the same VIN ( Vehicle Id number) on a multiple slips of paper, hence all slips on your hand refer to the same car. What if you write 'paint blue' on one slip and 'paint red' on another? well this demonstrates that the slips can only contain the VIN (object address) and all other information is stored in the car itself.

If you are interested in getting the car painted at the workshop, you don't have to send a slip, you can just tell them the VIN...that's only need to know, the value- pass by val. You still keep your slip and they can't change what's written on your slip...hence it is safer. Therefore they write down the VIN on their own slip - copy of the reference.

On the other hand you may ask a collegue to get the slip for last washed car from the shelf, go to the forecourt and choose a car that is not last washed car and return the slip with the new VIN of the washed car written on it - by ref. Actual slip is used and you have refered to the address of the actual slip (shelf) so that he gets the slip from there. He better not lose it or get it wet...less safe.

In all this palava, no-one is talking about copying, taking or moving the actual car as this is NOT refering to value types.


It's passed by value, if you intended to pass it by reference, you would use the ref parameter modifier. Not sure though whether this is allowed in constructors...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜