24

Common question but I could use an "english" explanation.

Is it like Java where

Cat myCat

actually is a pointer to Cat?

Should I really create copy constructors in C#?


I understand we are passing by value, but now my question is are we passing by pointer value or full copy of the object?

If it's the latter, isn't that too expensive performance/memory wise? Is that when you have to use the ref keyword?

Ondrej Slinták
  • 31,386
  • 20
  • 94
  • 126
masfenix
  • 7,736
  • 11
  • 45
  • 60

4 Answers4

57

As @rstevens answered, if it is a class, myCat is a reference. But if you pass myCat to a method call, then the reference itself is passed by value - i.e. the parameter itself will reference the same object, but it's a completely new reference, so if you assign it to null, or create a new object, the old myCat reference will still point to the original object.

SomeMethod(myCat);

void SomeMethod(Cat cat)
{
    cat.Miau(); //will make the original myCat object to miau
    cat = null; //only cat is set to null, myCat still points to the original object
}

Jon Skeet has a good article about it.

Jordan Ryder
  • 2,336
  • 1
  • 24
  • 29
Sunny Milenov
  • 21,990
  • 6
  • 80
  • 106
14

Remember that a pointer is not exactly the same as a reference, but you can just about think of it that way if you want.

I swear I saw another SO question on this not 10 minutes ago, but I can't find the link now. In the other question I saw, they were talking about passing arguments by ref vs by value, and it came down to this:

By default in .Net, you don't pass objects by reference. You pass references to objects by value.

The difference is subtle but important, especially if, for example, you want to assign to your passed object in the method.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
3

If you delacred Cat as

class Cat {...}

then it is.

If you delcared Cat as

struct Cat {...}

then your variable "is" the structure itself.

This is the difference between reference types and value types in .Net.

mmmmmmmm
  • 15,269
  • 2
  • 30
  • 55
0

Yes, it's about pointers but not really... The thing that messed me up originally is that it isn't really about about protecting your variable from changes within the method. If you change the object within the method, those changes are visible to the external methods regardless of whether it is passed in "ref" or not.

The difference (as I understand it) is whether the variable you send in has its reference updated coming back out if you change the object that variable references. So given this method

public void DoSomething(ref CoolShades glasses)
{
    glasses.Vendor = "Ray Ban";
    glasses = new CoolShades();
}

the variable you passed in as a parameter now contains a reference to the new CoolShades rather than whatever object it referenced before. The original parameter object's Vendor property will be changed to "Ray Ban" regardless of whether you passed the parameter ref or not.

Jacob Proffitt
  • 12,664
  • 3
  • 41
  • 47