Question

I wrote this code in visual studio.

public class Class1
 {
    public string MySTR;
 }


private static void func1(Class1 class )
 {
  class = new Class1();
  class.MySTR = "B";
 }

private static void func2(Class1 class )
{
  class.MySTR = "C";
}

static void Main(string[] args) 
{       
  Class1 class = new Class1();
  class.MySTR = "A";
  func1(class);
  Console.WriteLine(class.MySTR);
  func2(ref class);
  Console.WriteLine(class.MySTR);
}

I expected to get AA but I got AC.

What the difference between these methods?

Thank you.

Was it helpful?

Solution

Why you expect to get "AA"? "AC" is correct output. Check comments in following code blocks (codes has been modified slightly to make it compile and run) :

private static void func1(Class1 class1)
{
    //create new instance of Class1
    class1 = new Class1();
    //modify the new instance. 
    //Original instance passed to method parameter remain untouched
    //Hence you still got "A" from 1st Console.WriteLine(class1.MySTR);
    class1.MySTR = "B";
}

private static void func2(Class1 class1)
{
    //modify Class1 instance passed to method parameter. 
    //It's MySTR member value becomes "C" after this
    //Hence you got "C" from 2nd Console.WriteLine(class1.MySTR);
    class1.MySTR = "C";
}

static void Main(string[] args)
{
    Class1 class1 = new Class1();
    class1.MySTR = "A";
    func1(class1);
    Console.WriteLine(class1.MySTR);
    func2(class1);
    Console.WriteLine(class1.MySTR);
}

OTHER TIPS

Yes it's correct,

When you passed by ref it will pass by the address and update the value on that address so how it works.

First you have created a object so object has been created on heap and one address is assigned to that object and you have assigned a MySTR="A" so now the value of MySTR is A now you called the function 1 so it will go into function 1 with MySTR="A" now over there you have a reinitialize that object so one another object is being created on different address and you have assigned the value of MySTR="B" now you tried to print cl.MySTR where the value A is already store so first output is A

in second part you have passed the address of that object and tried to changed the value in same object so it would be C.

you code should be look like

class Program

{

    static void Main(string[] args)
    {
        Class1 cl = new Class1();
        cl.MySTR = "A";
        func1(cl);
        Console.WriteLine(cl.MySTR);
         func2(ref cl);
         Console.WriteLine(cl.MySTR);
         Console.ReadLine();
    }

    private static void func1(Class1 cla)
    {
        cla = new Class1();
        cla.MySTR = "B";
    }
    private static void func2(ref Class1 clas)
    {
        clas.MySTR = "C";
    }
}
public class Class1
{
    public string MySTR;

}

har07 has it right.

To clarify further, reference types (such as classes) are always passed by reference in C#. I assume you're coming from C(++) background, so imagine that the function is actually func2(Class1 *class1).

The ref keyword (which has to be in both the method and its call, no mixing) will pass the reference by reference, ie. func2(Class1 **class1). This allows you to return a new instance (the way you perhaps tried to do so in func1).

Structs and other value types, on the other hand, are by default passed by value, ie. func(Struct1 s). Using ref with structures is trickier, but effectively it mostly works like func(Struct1 **s), ie. you can assign values to the struct fields, and you can pass back a whole new struct "instance".

Another "reference by reference" variant is the out keyword, which is something like a promise to the caller - you don't pass an existing reference, but the callee has to pass a reference back:

void DoStuff(out int num)
{
  num = 23;
}

void SomeOtherFunction()
{
  int myNum;

  DoStuff(out myNum);

  // myNum now contains the value 23
}

The value myNum has before the call doesn't matter (in my sample, the variable is actually "undefined" - passing it by ref or by value would cause a compiler error), and the callee (DoStuff) must assign all its out parameters before returning.

class is refrence type ok this code return "B"

using System;
namespace ConsoleApplication2
{
    public class Class1
    {
        public string MySTR;
    }
    class Program
    {
        private static void func1(Class1 c )
         {
          //c = new Class1();
          c.MySTR = "B";
         }

        private static void func2(Class1 c )
        {
          c.MySTR = "C";
        }

        static void Main(string[] args) 
        {       
          Class1  c = new Class1();
          c.MySTR = "A";
          func1(c);
          Console.WriteLine(c.MySTR);
          //func2(ref c);Error
          //Console.WriteLine(c.MySTR);
          Console.ReadKey();
        }
    }
}

The 2 methods are declared as static which means they are instance-independant. If you change them in func1 it is changed across all the instances of Class1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top