METHOD PARAMETERS IN C SHARP, PASSING THE PARAMETERS INTO VALUE TYPES

using System;
namespace Modificatori_Ref_Out_In
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 10;
            Console.WriteLine(x);//x=10
            MyMethod(x);
            Console.WriteLine(x);//x=10
        }
        static void MyMethod(int y)
        {
            y=20;
        }
    }
}

Before addressing the topic “C sharp method parameters” let’s analyze the default behavior of value types and reference types when they are passed as parameters to a method. As you can see when you pass a value type, like an int is, to a method you already know that the passage happens by value, that is, a copy of the value of x is passed to y. By modifying y inside the static method we are actually modifying the copy of x which, when returning from the method, finds its unaltered value. This is the standard behavior of value types. Let’s see how a reference type behaves when we pass its reference to a method.

METHOD PARAMETERS IN C SHARP PASSAGE OF PARAMETERS IN REFERENCE TYPES

using System;
namespace Modificatori_Ref_Out_In
{
    public class MyClass
    {
        public int x = 10;
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            Console.WriteLine(mc.x);//x=10
            MyMethod(mc);
            Console.WriteLine(mc.x);//x=20
        }
        static void MyMethod(MyClass y)
        {
            y.x=20;
        }
    }
}

In the passage of the reference types, a copy by value takes place here too, but a copy of the references takes place, the reference of mc is passed to y. Both references point to the same object so if we change the variable x in MyMethod we actually change the state of the object pointed to by the two references mc and y. If we point y to a new instance of MyClass then the reference mc would not be affected and the value of the variable x remains unchanged.

using System;
namespace Modificatori_Ref_Out_In
{
    public class MyClass
    {
        public int x = 10;
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            Console.WriteLine(mc.x);//x=10
            MyMethod(mc);
            Console.WriteLine(mc.x);//x=10
        }
        static void MyMethod(MyClass y)
        {
            y= new MyClass();
            y.x=20;
        }
    }
}

y now points to a new reference independent of mc, for this reason the value of x remains unchanged.

MODIFIER REF

using System;
namespace Modificatori_Ref_Out_In
{
    public class MyClass
    {
        public int x = 10;
    }
    class Program
    {
        static void Main(string[] args)
        {
            int z = 10;
            MyClass mc = new MyClass();
            Console.WriteLine($"{"x= "+mc.x + " "  + z= "+z}");//z=10,x=10
            MyMethod(ref mc, ref z);
            Console.WriteLine($"{"x= "+mc.x + " "  + z= "+z}");//z=20,x=20
        }
        static void MyMethod(ref MyClass y, ref int k)
        {
            y.x=20;
            k=20;
        }
    }
}

To pass a reference parameter to a method, the ref keyword must be specified both within the method and at the time of invocation. As you can see from the code as regards the reference types the behavior does not change, instead passing a value type this time the value of z has changed. The variable z and this is very important must have a value already assigned, while for the reference variables you can also pass null. To better understand what happened we must consider that:

  • When we pass the parameters by value, memory is allocated on the stack for the parameters of a method and this memory is separate from the initial value of the arguments passed.
  • When we pass by ref further memory is not allocated in the stack the parameters themselves become aliases for the original values ​​of the arguments, i.e. they share the same memory as the arguments and it is for this reason that a modification of the parameters within the method causes a modification of the original arguments.

 
using System; 
namespace Modificatori_Ref_Out_In 
{ 
public class MyClass 
{ 
    public int x = 10; 
} 
class Program 
{ 
    static void Main(string[] args) 
    {
        MyClass mc = new MyClass(); 
        Console.WriteLine($"{mc.x}");//x=10
        MyMethod(ref mc); Console.WriteLine($"{mc.x}");//x=20 
    } 
    static void MyMethod(ref MyClass y)   
    { 
        y= new MyClass(); y.x=20; 
    } 
  } 
} 

This time the behavior is different from what we saw before, the new object is created within MyMethod, the original instance variable mc is overwritten with the new value pointed to by y, both mc and y point to the new object created in the method.

THE OUT MODIFIER

This type of modifier outputs values from a method, in addition to the return statement which can only return one value. Let’s see an example:

using System;
namespace Modificatori_Ref_Out_In
{
    public class MyClass
    {
        public int x = 10;
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc;
            int k;
            MyMethod(out mc,out k);
            Console.WriteLine($"{mc.x} {k}");//x=20, k=20
        }
        static void MyMethod(out MyClass y, out int k)
        {
            y= new MyClass();
            y.x=20;  
            k=20;
        }
    }
}

Very often the arguments of the methods that return output values are not assigned, it is mandatory to initialize them in the method if you do not want to receive an error from the compiler.

MODIFIER IN

This modifier is used to make the passed parameters read-only, read-only, that is, within the method they will not be modified. The only thing that is allowed to change are the attributes of the MyClass class but not the reference to the object.

using System;
namespace Modificatori_Ref_Out_In
{
    public class MyClass
    {
        public int x = 10;
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            int k = 10;
            MyMethod(mc,k);
            Console.WriteLine($"{mc.x} {k}");//x=20, k=10
        }
        static void MyMethod(in MyClass y, in int k)
        {
            //y= new MyClass();COMPILER ERROR
            //k=20;COMPILER ERROR
            y.x=20;  
        }
    }
}

LINK TO PREVIOUS POST

LINK TO THE CODE ON GITHUB