2

The application is printing 24 but shouldn't it be printing 18 when we know that without ref keyword only a copy of object is passed and no change is made to the original object. I have created a class called myclass and an object me. age is a public variable in class myclass. I have set me.age as 18 and through the method show I have changed it to 24.

class Program
{        
    static void Main(string[] args)
    {
        myclass me = new myclass();
        me.age = 18;
        show(me);
        Console.WriteLine(me.age);
        Console.ReadLine();
    }

    public static void show( myclass you)
    {
        you.age = 24;        
    }
}

class myclass
{
    public int age;
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders May 24 '13 at 00:08
  • "without ref keyword only a copy of object is passed and no change is made to the original object" is incorrect. A correct statement is "without the `ref` or `out` keyword a copy of the *value* is passed; no change is made to the original *variable* if the *value* came from a *variable*." `ref` makes an alias to a *variable*. – Eric Lippert May 24 '13 at 02:40

5 Answers5

2

It's printing the right thing.

myclass is an object, and the default behavior is to pass the reference of the object in C#, so when you don't specify anything, you pass the reference.

If you declare struct myclass though, you'll have the behavior you want, because structs aren't references by default.

ppetrov
  • 3,077
  • 2
  • 15
  • 27
  • This is quite confusing. `struct`s inherit from `Object`, but they are not objects? And if this is just by default, does that mean you can pass an instance of a `class` by value? – svick May 24 '13 at 00:53
  • In c# everything inherits from `Object`. But `struct` inherits first from `System.ValueType` (which then inherits from `Object` btw). The difference is made at the compiler level. When the compiler "sees" that something inherits from `System.ValueType` it passes the value, when it doesn't inherit from `System.ValueType` it passes the reference. – ppetrov May 24 '13 at 01:20
  • take a look at this post: http://stackoverflow.com/questions/13049/whats-the-difference-between-struct-and-class-in-net there's a good explanation of the differences between a class and a struct – ppetrov May 24 '13 at 01:22
2

Don't confuse the variable and what the variable points to.

When you have:

MyClass myVar = new MyClass();
MyClass myVar2 = myVar;

That will create only a single instance of an object, but 2 variables pointing to it.

The same thing is happening to your parameter: you is a copy of the variable me, but both point to the same object. So when you modify you.age, you are also modifying me.age.

In your function, if you then did

you = new myClass();

only then would me and you refer to different objects. If you did this, me would still point to the original object.

If you added ref to the parameter you, then if you did

you = new myClass();

then the variable me would be updated to point to that same object.

For objects, you need to separate the variable from what the variable points to.

Matt Houser
  • 33,983
  • 6
  • 70
  • 88
2

You're probably confusing this with C++ classes. In C#, classes are reference types, which means that whenever you have a variable of a type that's class, that variable doesn't hold the object itself, it holds only a reference to it (you can think of it as a pointer). So, when you pass your object into a method, you actually pass a reference to that object. This means the behavior you're observing is correct.

C# also supports value types (unlike e.g. Java), which you create by using struct instead of class. If you changed myclass into a srtuct, you would get the behavior you expected.

svick
  • 236,525
  • 50
  • 385
  • 514
1

You are confusing value types and reference types.

public void addTwo(int a)
{
    a += 2;
}

...

int a = 5;
addTwo(a);
Console.WriteLine(a); // will give "5";

public void addTwo(ref int a)
{
    a += 2;
}

...

int a = 5;
addTwo(ref a);
Console.WriteLine(a); // will give "7";

For reference types (anything that is defined as class instead of struct, what you are passing on is a reference to the object, not a copy. So you are in fact changing the object.

Jan Dörrenhaus
  • 6,581
  • 2
  • 34
  • 45
0

You are sending an object to your function.

Not an atomic type or a struct, therefor it is sent by reference (this is how C# works), anything you change in this object in the function will also change in the original object because it is the same.

More information about passing parameters: http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx

Adam Tal
  • 5,911
  • 4
  • 29
  • 49