Solved

By Value or By reference C#

Posted on 2014-03-20
7
236 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
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
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

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

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

For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
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…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

776 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