Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

By Value or By reference C#

Posted on 2014-03-20
7
Medium Priority
?
248 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 30

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
Fill in the form and get your FREE NFR key NOW!

Veeam® is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.

 
LVL 30

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 30

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 30

Accepted Solution

by:
anarki_jimbel earned 2000 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

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

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

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
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…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…

705 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