Solved

By Value or By reference C#

Posted on 2014-03-20
7
232 Views
Last Modified: 2014-03-20
Expert,

I have basic question, I expect app Print 'Mary' as result, but it Print 'Mike",  It looks result is changed, I didn't use word 'ref' in second call, but it treat like reference type. Could you explain  why?


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
   
    class Program
    {
        static void Main(string[] args)
        {

            MyClass test = new MyClass();

            //1
            //test.strTest = "Mary";
            //SomeFunction(ref test);
            //Console.WriteLine(test.strTest);

            //2
            test.strTest = "Mary";
            SomeFunction(test);
            Console.WriteLine(test.strTest);

            Console.Read();
        }


        //static void SomeFunction(ref MyClass inst)
        //{
        //    inst.strTest = "Mike";
        //}

        static void SomeFunction(MyClass inst)
        {
            inst.strTest = "Mike";
        }
    }

    public class MyClass
    {
        public string strTest;
    }

}

Open in new window


Thanks a lot.
0
Comment
Question by:dshi15
  • 4
  • 3
7 Comments
 
LVL 29

Expert Comment

by:anarki_jimbel
ID: 39943571
Ref has nothing to do with your result.

When you pass any string (Mary etc) to a method, you set instance string Mike. Then you print this instance string - and you see "Mike". That's it...

Specifically, this method alterates the string, and does not matter what value you set before:

        static void SomeFunction(MyClass inst)
        {
            inst.strTest = "Mike";
        }

Open in new window


And yes, keep in mind, that objects are passed as referenced types :). In other words, you pass an address of your object to the method, therefore the original object is modified.
0
 
LVL 1

Author Comment

by:dshi15
ID: 39943658
Thank you, but could you explain more, I'm learner and I can understand the following code from Microsoft  website,

class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by value. 
        // The value of arg in Main is not changed.
        arg = 4;
        squareVal(arg);
        Console.WriteLine(arg);
        // Output: 4 

        // Passing by reference. 
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16 
    }

    static void squareVal(int valParameter)
    {
        valParameter *= valParameter;
    }

    // Passing by reference 
    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}

Open in new window


I passed an object SomeFunction(test);
I'm confused.
0
 
LVL 1

Author Comment

by:dshi15
ID: 39943713
Got it, I missed this line

>>And yes, keep in mind, that objects are passed as referenced types :). In other words, you pass an address of your object to the method, therefore the original object is modified.


You mean use 'ref ' or not, no difference here?
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 29

Expert Comment

by:anarki_jimbel
ID: 39943716
OK, it needs a bit more explanation. With value types its pretty easy. See my comments inline:

    static void Main(string[] args)
    {
        int arg;

        // Passing by value.
        // The value of arg in Main is not changed.
        arg = 4;
        squareVal(arg);
//anarki comment: when passing by value, we create a COPY of original value and use it //inside the method; therefore, our original value is not changed - only COPY is changed!
        Console.WriteLine(arg);
        // Output: 4

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
// now we do not create a copy. We, roughly speaking, pass an address of the value in the //memory (aka "pointer"). And therefore if you make some operations with this arg number //- we change the original! And when print - we print altered original!
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

Hope this is pretty clear. Let me few minutes to prepare an example for objects - it's a bit more complex :).
0
 
LVL 29

Expert Comment

by:anarki_jimbel
ID: 39943719
"...You mean use 'ref ' or not, no difference here?..."

There is difference but pretty subtle. I will write an example to explain.
0
 
LVL 29

Accepted Solution

by:
anarki_jimbel earned 500 total points
ID: 39943799
OK, when you pass an object as "value" - you may change object's content but not object itself. Think what happens behind scenes: you pass just an address to the object, not really object itself. And because this address (which is basically an integer)  is passed as "value" - you cannot change it by code from inside the invoked method.

With 'ref' - you can. Please see my code to illustrate the concept and comments in code:

        private void button1_Click(object sender, EventArgs e)
        {
            MyObject obj = new MyObject();// remember - default name is "default"
            //expect change of original object content but not object itself
            passObjectByValue1(obj);
            System.Diagnostics.Debug.WriteLine(obj.name);// expect "original obj name changed"

            obj.name = "default"; //restore default name
            //expect no changes in the original object
            passObjectByValue2(obj);
            System.Diagnostics.Debug.WriteLine(obj.name);// expect "default"

            obj.name = "default"; //restore default name
            //expect changes of the original object itself
            passObjectByRef(ref obj);
            System.Diagnostics.Debug.WriteLine(obj.name);// expect "changed object by ref"
        }

        //basically, we pass an address for object "o" here, and we CANNOT change it from inside
        private void passObjectByValue1(MyObject o)
        {
            o.name = "original obj name changed";// we are changing a name for ORIGINAL object; 
            //yes, we can alter content of original object!

            //Now create new one and change it
            o = new MyObject(); 
            o.name="changed object";// this will NOT affect the original object outside the method
        }

        private void passObjectByValue2(MyObject o)
        {
            //Now we do not chage original object  - we only create and change new one
            o = new MyObject(); 
            o.name="changed object";// this will NOT affect the original object outside the method
        }

        // here we pass an address of the object (like integer ) by reference - therefore 
        // we may replace the original object from inside the method
        private void passObjectByRef(ref MyObject o)
        {
            //Now we REPLACE the original object with new one!
            o = new MyObject(); 
            o.name="changed object by ref";// this WILL affect the original object outside the method
        }

        class MyObject
        {
            public string name;

            public  MyObject()
            {
                name = "default";
            }
        }

Open in new window



Output:

original obj name changed
default
changed object by ref
0
 
LVL 1

Author Closing Comment

by:dshi15
ID: 39943814
Thank you very much.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
As a trusted technology advisor to your customers you are likely getting the daily question of, ‘should I put this in the cloud?’ As customer demands for cloud services increases, companies will see a shift from traditional buying patterns to new…

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now