Click here to Skip to main content
15,352,915 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
public class Class1
    {
        private int Prop1;

        public int MyProperty1
        {
            get { return Prop1; }
            set { Prop1 = value; }
        }
    }

    protected void Button2_Click(object sender, EventArgs e)
    {
        Class1 oClass1 = new Class1();
        oClass1.MyProperty1 = 10;
        MethodCall(oClass1);
        TextBox2.Text = oClass1.MyProperty1.ToString();
    }

    public void MethodCall(Class1 oclass)
    {
        oclass.MyProperty1 = 100;
    }


Above code gives TextBox.Text as 100.
These values are changed in a function which gets class1 object as parameter but not by reference. But still change in value in method is reflected in calling method.
This doesn't happen with int or Int32.

Can anybody please explain me the reason ?
Thanks in advance.

[edit]Code block added to preserve formatting - OriginalGriff[/edit]
Posted
Updated 13-Aug-10 1:16am
v2
Comments
[no name] 19-Dec-13 12:53pm
   
Pankajbendre don't feel alone *lol*. c# makes everything easier and more clear *lol*^2. In the beginning I fighted also a lot of times with these things. It is like it is, we have to learn/accept it ;)
Next step is when you have to "fight" with garbage collector....

Oh boy - this is going to be difficult to explain without pictures, so you would be better off looking in a book. But:

In your click handler, you create an instance of Class1, and assign it to a variable called oClass1. What is actually in oClass1? Is it an int - the total data stored by Class1? Or is it something else?
What is actually stored in oClass1 is not the actual Class1 instance - it is a reference to the class instance. I.e. the instance you created is on the heap and oClass1 is (probably) on the stack. Why? So that you could have a second variable if you needed it:
protected void Button2_Click(object sender, EventArgs e)
{
    Class1 oClass1 = new Class1();
    Class1 oClass2 = oClass1;
    oClass1.MyProperty1 = 10;
    MethodCall(oClass1);
    TextBox2.Text = oClass1.MyProperty1.ToString();
}
And then both oClass1 and oClass2 would refer to the same instance of a Class1.
With me so far? Good.
You then hand the content of oClass1 to your method. What gets handed through? Answer: the reference to the instance. Not oClass1, but the content of oClass1.
So when you modify MyProperty in MethodCall you are modifying the object that oClass1 refers to.

This is a lot easier to explain with pictures!

Try this and you might see what I mean:
class Class1 { public int i;}
private void ShowTheDifference()
    {
    Class1 cs = new Class1();
    cs.i = 100;
    Method(cs);
    MessageBox.Show(cs.i.ToString());
    Method2(cs);
    MessageBox.Show(cs.i.ToString());
    }
void Method(Class1 cs) { cs = new Class1(); cs.i = 999; }
void Method2(Class1 cs) { cs.i = 999; }
   
Anything other than ValueTypes are passed by reference. ValueTypes includes structures.
Int32 is a structure, so it is passed by value.

Your custom object TextBox or any object (which is not ValueType)is always passed by Reference.
   
No! Both, value and reference types are passed by value unless you require them to be passed by reference (the ref or out keywords). Since Class1 is a reference type its value is a reference pointing to some object stored on the heap. Thus, changing the value of a property of a reference to oclass in MethodCall changes the value of oclass.MyProperty on the heap.

public void MethodCall(Class1 oclass)    {        oclass.MyProperty1 = 100;    }


If you want to pass by reference use ref:

public void MethodCallByRef(ref Class1 oclass) {
int tOldValue = oclass.MyProperty1;
oclass = new Class1();
oclass.Property1 = tOldValue;
}


then you have:

...

Class1 o1 = new Class1();
Class1 o2 = o1;

MethodCall(o2);

Console.Write(Object.Equals(o1.Property1, o2.Property1));// prints true
Console.Write(Object.ReferenceEquals(o1, o2)); // prints true

MethodCallByRef(ref o2); // explicit call by reference!

Console.Write(Object.Equals(o1.Property1, o2.Property1)); // prints true!
Console.Write(Object.ReferenceEquals(o1, o2)); // prints false!
...
   
v2
Comments
Roger Wright 15-Aug-10 3:01am
   
Reason for my vote of 1
Answer is dead wrong; ref is used to override the default behavior.
[no name] 19-Dec-13 15:04pm
   
Yes continue like this until nobody will answer a question. Placing the right comment and vote neutral (3) would be appropriate. A lot of you "high point members" do react in the last time as they where gods :(
Paul Michalik 15-Aug-10 7:57am
   
I am sorry? That is exactly what the first sentence of my post says. Everything is passed by value, unless you explicity require passing by "ref". The key point which is often misunderstod by beginners is that the value of a reference type is a reference (actually a pointer) to object on the heap... You should correct (or better re-write) answer 3, since it contains several misleading statements.
All register types are default by value, like int, int32 and also reference pointers (not directly visible in c# but they are there). These variables live on the stack and are there only alive in the stackframe of that method call. An object lives on the heap and only the reference lives on the stack. So when changing an object property it is done to the referenced object and therefore can be seen by everyone with a reference to that object. It is an optimization because it means that the object doesn't have to be copied every time it is passed. If it must stay the same you could clone it using that method accordingly.

This is however language specific because c/cpp for example will create copies of structs/objects if you do not explicitly specify differently.

Hopefully this gave you some idea.

Good luck!
   
The answers above are correct, but I find them confusing. I'm a beginner and rather simpleminded, to boot. In simpler terms, objects are passed to methods by reference, while simple types like int and int32 are passed by value. The difference is easy to understand.

When you pass a simple type to a method, the method gets a copy of the original variable. If the method changes that value, when the method returns the original variable is unchanged, and the copy used in the method is destroyed.

When you pass an object, the method gets the address of the original variable, and when the method makes a change, the original gets changed. Passing variables by reference sort of opens a pipeline to the original variable, and gives your method access to it.

If you want to preserve the changed value of a simple type, give your method a return type that matches the type used as a parameter, then use a return statement to pass the result out of the method:

public int32 MyMethod(int32 MyParam)
{
    int32 MyValue = 5 * MyParam;  //MyParam is a local copy of the input parameter
    return MyValue;
}

int32 MyChangedValue = MyMethod(MyParam);



I hope a simpleton's explanation is helpful... :)
   
A more pictoral reference is explained in the following link. I hope that helps for new comers like me.

http://www.javaranch.com/campfire/StoryPassBy.jsp[^]
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900