Solved

By Value or By reference C#

Posted on 2014-03-20
7
243 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
Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

 
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

Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

Question has a verified solution.

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

Suggested Solutions

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 …
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
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…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

820 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