-5
classes deal with the reference types and traditional data types deal with the value type just for example :
int i=5;
int j=i;
i=3 ; //then this will output i=3 and j=5 because they are in the different memory blocks .

Similarly if we talk about the object of a class say point class

class point
{
    public int x,y;
    void somefucnt(point p,int x)
    {
        Console.writeline("value of x is "+p.x);
        x=22;
        Console.writeline("value of x is "+p.x);
    }
}
class someotherclass
{
    static void Main(string [] args )
    {
        p1.x=10;
        p1.somefunct(p1,p1.x); 
    }
}

Both console.write statements are printing 10 , despite ive changed x to some other value ? why is it so ?since p is just the reference to x so it should be updated by changing values of x . this thing is really confusing me alot .

user2864740
  • 60,010
  • 15
  • 145
  • 220

4 Answers4

1

The observed behavior has nothing to do with Value types vs Reference types - it has to do with the Evaluation of Strategy (or "calling conventions") when invoking a method.

Without ref/out, C# is always Call by Value1, which means re-assignments to parameters do not affect the caller bindings. As such, the re-assignment to the x parameter is independent of the argument value (or source of such value) - it doesn't matter if it's a Value type or a Reference type.

See Reference type still needs pass by ref? (on why caller does not see parameter re-assignment):

Everything is passed by value in C#. However, when you pass a reference type, the reference itself is being passed by value, i.e., a copy of the original reference is passed. So, you can change the state of object that the reference copy points to, but if you assign a new value to the reference [parameter] you are only changing what the [local variable] copy points to, not the original reference [in the argument expression].

And Passing reference type in C# (on why ref is not needed to mutate Reference types)

I.e. the address of the object is passed by value, but the address to the object and the object is the same. So when you call your method, the VM copies the reference; you're just changing a copy.


1 For references types, the phrasing "Call By Value [of the Reference]" or "Call by [Reference] Value" may help clear up the issue. Eric Lippert has written a popular article The Truth about Value Types which encourages treating reference values as a distinct concept from References (or instances of Reference types).

Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220
0
void somefucnt(point p,int x){
Console.writeline("value of x is "+p.x);

x=22;
Console.writeline("value of x is "+p.x);

}

Here, the x=22 won´t change p.x but the parameter x of (point p,int x)
Normally, your assumtion about values/references is ok (if I understood it correctly).

Tip: Google for c# this instead of passing a object to it´s own method

deviantfan
  • 11,268
  • 3
  • 32
  • 49
0

You change the value of the parameter (x), not the value of p.x, value types are passed by value unless you use the ref keyword.

Like in your first example, there is no relationship between i and j as well as the parameter x, and p1.x.Each variable has it's own space in the memory.So changing one of them doesn't affect to the other.

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • `ref` affects *variables*, not *values*. The first clause holds true for both Reference and Value types and I find the second misleading in context as Reference types are *also* Call by Value (albeit always of the *reference value*). – user2864740 May 10 '14 at 20:02
0

You have two different variables named x in the somefucnt function. One is the member variable x which you are trying to change, the other is the function input parameter in void somefucnt(point p, int x). When you say x = 22, the input parameter x is changed instead of the member variable x.

If you change the line x = 22 to this.x = 22 then it should work as you expect.

Side note:

A good practice to avoid confusion is to always have class members private and name them as _x. Otherwise, have public auto properties in CamelCase, like this:

public int X { get; set; }

These methods avoid ambiguity between class variables and function input variables.

metacubed
  • 7,031
  • 6
  • 36
  • 65
  • Is anything wrong with this answer? Please explain the down-vote. – metacubed May 10 '14 at 20:09
  • I can't find anything wrong - I changed the ordering to bring the focus of the answer forward, as the initial perception can play a big factor. – user2864740 May 10 '14 at 20:26
  • your 2nd half of ans will too solve that problem , then what if there is a scenario where i ve to pass an object(what u can say a reference ) of a class into the method of inherited class or itself . i know thats sounds buzzy but at that point properties wont work . So can u elaborate that thing any further ? – Nasir Ul Islam Butt May 10 '14 at 23:22