Solved

By Value or By reference C#

Posted on 2014-03-20
7
244 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
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 
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 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

[Webinar] Code, Load, and Grow

Managing multiple websites, servers, applications, and security on a daily basis? Join us for a webinar on May 25th to learn how to simplify administration and management of virtual hosts for IT admins, create a secure environment, and deploy code more effectively and frequently.

Question has a verified solution.

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

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
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…
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…

751 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