C#. Parameters of methods. Modifiers ref and out. Examples. Differences between ref and out modifiers




Parameters of methods. Modifiers ref and out. Examples. Differences between ref and out modifiers


Contents


Search other websites:

1. The use of the modifier parameter ref. What is the assignment of the ref parameter modifier?

The ref modifier is intended to indicate that the method parameter should be passed by reference and not by value. In other words, if a method must be forced to pass an argument by reference, when declaring a method, the modifier ref must be specified before the corresponding formal parameter.

The parameter modifier ref is used in the description of the formal parameter of the method. The modifier parameter ref is specified before the type of the formal parameter, as shown below:

ref type param

The general form of a method in a class that receives the formal parameter ref is as follows:

access return_type MethodName(ref type param)
{
    // ...
}

where

  • MethodName – the name of method;
  • access – access type to the method (private, protected, public, internal);
  • return_type – type, returned by method;
  • type – the type of parameter named param, which receives method;
  • param – the name of formal parameter.

When calling such a method from another code, the modifier ref is also set before the parameter:

MethodName(ref argument);

where argument – the argument that is passed to the method. This is required by the C # syntax.

 

2. Examples of methods that use the ref modifier

Example 1. Implementing a method that multiplies a number by 5. Number is an input parameter of the method. The method gets the value of a number, multiplies it by 5 and returns with the help of the modifier ref.

// a method that multiplies a number by 5
public void Mult5(ref int x)
{
    x = x * 5;
}

Calling Mult5() from another program code

int d = 10;
qe.Mult5(ref d); // d = 10*5 = 50

After the call, the value of the variable d becomes equal to 50. According to the syntax of C#, before calling the variable d, you must set the modifier parameter ref.



Example 2. Solving a quadratic equation. A QuadraticEquation class is set, containing data and a method for solving a quadratic equation.

The class implements the Calc() method, which receives two parameters x1, x2 with the modifier ref. These parameters change their values in the method, in case the equation has a solution.

// a class that implements the data and a method for solving a quadratic equation
class QuadraticEquation
{
    public double a, b, c;

    // constructor of class, gets the parameters a, b, c of equation
    public QuadraticEquation(double _a, double _b, double _c)
    {
        if (IsSolution(a, b, c))
        {
            a = _a;
            b = _b;
            c = _c;
        }
        else
            a = b = c = 0;
    }

    // internal method that determines whether a solution with given a, b, c
    bool IsSolution(double a, double b, double c)
    {
        double d = b * b - 4 * a * c;
        if (d < 0) return false;
        return true;
    }

    // Method that solves quadratic equation
    // The method returns true and the result is in x1, x2, if the equation has a solution,
    // otherwise, the method returns false
    public bool Calc(ref double x1, ref double x2)
    {
        // checking whether the equation has a solution
        if (!IsSolution(a, b, c))
            return false;

        // if there is a solution, then x1, x2 are calculated
        double d = b * b - 4 * a * c;
        x1 = (-b - Math.Sqrt(d)) / (2 * a);
        x2 = (-b + Math.Sqrt(d)) / (2 * a);

        return true;
    }
}

Calling a method from another class may be as described below.

class Program
{
    static void Main(string[] args)
    {
        // creating an object of class QuadraticEquation
        QuadraticEquation qe = new QuadraticEquation(2, -8, 5);

        double x1 = 0, x2 = 0;

        if (qe.Calc(ref x1, ref x2)) // call the Calc() method, before x1, x2 modifier ref is set
        {
            // if there is a solution, then derive the roots of the equation x1, x2
            Console.WriteLine("x1 = {0}", x1);
            Console.WriteLine("x2 = {0}", x2);
        }
        else
            Console.WriteLine("Equation has no roots.");
        return;
    }
}

It should be noted that when calling the Calc() method, the ref modifiers must be specified:

Calc(ref x1, ref x2)

Example 3. String s is given. Develop a method that removes the given character c from string s. The character c is an input parameter-value. String s must be a reference parameter and result.

Below is the Str class with the implementation of the DeleteSymbol() method. A call to the DeleteSymbol() method from the Main() function is also demonstrated.

class Str
{
    // the method removes the character c from string s
    public void DeleteSymbol(ref string s, char c)
    {
        string s2="";

        for (int i=0; i<s.Length; i++)
            if (s[i] != c)
                s2 = s2 + s[i];
        s = s2;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Str S = new Str();
        string str = "This is a textbook.";
        // call the DeleteSymbol() method
        S.DeleteSymbol(ref str, 'i'); // str = "Ths s a textbook."
        Console.WriteLine(str);
        return;
    }
}

 

3. Applying the ‘out’ parameter modifier. What is the purpose of the out parameter modifier?

The out parameter modifier is used if two conditions are necessary:

  • the method does not need to pass the value;
  • the method must return a value using the parameter.

The out modifier for a parameter named param of typename type is specified at the beginning of its declaration.

out typename param

The general form of a method that takes one parameter with an out modifier is

access return_type MethodName(out typename param)
{
    // ...
}

where

  • MethodName – the name of method;
  • access – method access type (private, protected, public, internal);
  • return_type – the type, that the method returns;
  • type – the type of the parameter named param that method receives;
  • param – the name of formal parameter.

 

4. Examples of methods that use the out parameter modifier

Example 1. Develop a method that returns the number of Avogadro. The Avogadro number is specified by the method parameter.
Method text:

// The Avogadro number
void GetAvogadro(out double Avg)
{
    Avg = 6.022140857e23;
}

Calling a method from another program code

// calling the method GetAvogadro() from another method
double Avg;
GetAvogadro(out Avg); // specify modifier out - necessarily
// Avg = 6.022140857E+23

As can be seen from the above code, when calling a method that contains an out-parameter, you must specify the out modifier

GetAvogadro(out Avg);

Example 2. Develop a CalcEquation() method that solves a quadratic equation. The method receives the input parameters of the coefficients of the equation a, b, c. These parameters are passed by value to the equation.

The method returns the solution of the equation using the parameters x1, x2, which are declared with the out modifier.

The method returns true using the return operator if the equation has a solution. Otherwise, method returns false.
Below is the Program class, which implements the CalcEquation() method.

class Program
{
    static bool CalcEquation(double a, double b, double c, out double x1, out double x2)
    {
        double d;
        d = b * b - 4 * a * c;
        if (d>=0)
        {
            x1 = (-b - Math.Sqrt(d)) / (2 * a);
            x2 = (-b + Math.Sqrt(d)) / (2 * a);
            return true;
        }
        else
        {
            x1 = x2 = 0; // necessarily, otherwise an error
            return false;
        }
    }

    static void Main(string[] args)
    {
        // Demonstrate the use of the out parameter modifier
        bool res;
        double x1, x2;

        // calling the method
        res = CalcEquation(8, 3, -4, out x1, out x2);

        if (res)
        {
            Console.WriteLine("x1 = {0}", x1);
            Console.WriteLine("x2 = {0}", x2);
        }
        else
            Console.WriteLine("Equation has no roots.");
        return;
    }
}

Example 3. Develop a method that returns the name of a digit in a string.

// a class that implements a method that returns the name of a digit
class Number
{
    // output of the name of the number based on the input value num
    public void TextNumber(int num, out string text)
    {
        switch (num)
        {
            case 1: text = "one"; break;
            case 2: text = "two"; break;
            case 3: text = "three"; break;
            case 4: text = "four"; break;
            case 5: text = "five"; break;
            case 6: text = "six"; break;
            case 7: text = "seven"; break;
            default: text = ""; break;
        }
        return;
    }
}

Using the Number class’s TextNumber() method

Number nm = new Number(); // nm - object of class Number
string s;

nm.TextNumber(3, out s); // s = "three"
nm.TextNumber(8, out s); // s = ""
nm.TextNumber(1, out s); // s = "one'

 

5. What are the differences between ref and out modifiers?

There are three interrelated differences between the ref and out modifiers:

  • 1. A parameter with an out modifier is used only to return a value from a method. The parameter with the modifier ref can be used to return and set the value in the method to other variables. Therefore, before calling the method, there is no need to assign some value to a variable that is used with the out modifier.
  • 2. In the method, a variable declared with the out parameter is considered uninitialized. A variable declared with ref is considered as initialized. Therefore, you cannot use the out-variable on the right side of the assignment operator. But ref-variable you can use.
  • 3. If the parameter is declared with the out modifier, then in the body of the method some value must be assigned to this parameter. Otherwise there will be a compilation error. If the parameter is declared with the modifier ref, then is not necessary to assign value to this parameter in the method body.

 

6. Passing a reference to a class instance into the function using the ref modifier. Example

You can pass not only the value of the base types (int, double, char, etc.) to the function, but also the value of class instances (objects). If ref or out modifiers are used when passing a class object to a function, the reference itself is passed by reference. This allows you to change the object itself in the method.

Example. The example implements a method that replaces one class object with another. Both class objects are passed to the method as parameters. The object to be replaced is passed with the ref modifier.

using System;
using static System.Console;

namespace ConsoleApp2
{
  // Point class - implements a point on the coordinate plane
  class Point
  {
    // internal fields of the class
    int x;
    int y;

    // Constructor
    public Point(int x, int y)
    {
      this.x = x;
      this.y = y;
    }

    // The method of assigning one instance of a class to another:
    // point1 <= point2
    public void AssignmentPoint(ref Point point1, Point point2)
    {
      point1 = point2; // overriding of object point1
    }

    // Method that displays class field values
    public void Print(string text)
    {
      Write(text);
      WriteLine("x = {0}, y = {1}", x, y);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Passing object references as ref and out parameters
      // 1. Declare instances of classes
      Point pt1 = new Point(1, 2);
      Point pt2 = new Point(5, 6);

      // 2. Display instances of classes
      pt1.Print("Object pt1:");
      pt2.Print("Object pt2:");

      // 3. AssignmentPoint() method call - passing an object as a ref-reference
      pt1.AssignmentPoint(ref pt1, pt2); // pt1 <= pt2

      // 4. Display the instances of classes after assignment
      WriteLine("\nAfter AssignmentPoint");
      pt1.Print("Object pt1:");
      pt2.Print("Object pt2:");
    }
  }
}

The result of the program

Object pt1:x = 1, y = 2
Object pt2:x = 5, y = 6

After AssignmentPoint
Object pt1:x = 5, y = 6
Object pt2:x = 5, y = 6

After analyzing the result of the program, we can conclude. The AssignmentPoint() method completely replaced the pt1 object with the pt2 object. This is possible thanks to the modifier ref. If you remove the ref modifier from the first parameter of the AssignmentPoint() method, then the changes inside the method will not work in the calling code (main() function). To verify this, simply remove the ref modifier in the AssignmentPoint() method and in the call to this method.

 

7. Passing a reference to the class instance into the function using the out modifier. Example

An instance of the class can be passed to a function with the out modifier. With this transfer, you can change the instance of the class itself, as in the case of the ref-modifier.

Example. The example implements the FormArray() method, which forms a new object of the ArrayDouble class, allocating memory for it and filling it with an arbitrary values.

using System;
using static System.Console;

namespace ConsoleApp2
{
  // A class that implements an array of numbers
  class ArrayDouble
  {
    private double[] A; // array of numbers

    // Constructor with 1 parameter
    public ArrayDouble(int length)
    {
      // allocate memory for the array and fill it with zero values
      A = new double[length];
      for (int i = 0; i < A.Length; i++)
      {
        A[i] = 0.0;
      }
    }

    // Access methods
    public double GetAi(int index)
    {
      if ((index >= 0) && (index < A.Length))
        return A[index];
      else
        return 0;
    }

    public void SetAi(int index, double value)
    {
      if ((index >= 0) && (index < A.Length))
        A[index] = value;
    }

    // Method that displays the array
    public void Print(string text)
    {
      WriteLine(text);
      for (int i = 0; i < A.Length; i++)
      {
        Write("{0:f2}\t", A[i]);
      }
      WriteLine();
    }
  }

  class Program
  {
    // A method that fills the array A with random numbers,
    // the method forms an entirely new instance of the ArrayDouble class
    static void FormArray(out ArrayDouble A, int length)
    {
      // 1. Initialize the random number generator
      Random rnd_num = new Random();

      // 2. Allocate memory for instance A
      A = new ArrayDouble(length);

      // 3. Fill instance A with random numbers from 0 to 10
      for (int i = 0; i < length; i++)
      {
        A.SetAi(i, rnd_num.NextDouble() * 10);
      }
    }

    static void Main(string[] args)
    {
      ArrayDouble ad = null; // class instance ArrayDouble

      // Form the array ad
      // out parameter - an array is formed inside the FormArray() method
      Program.FormArray(out ad, 5);
      ad.Print("1 - Array ad:");

      // Re-form ad array
      FormArray(out ad, 7); // at the exit from the method - a new instance
      ad.Print("2 - Array ad:");
    }
  }
}

The result of the program

1 - Array ad:
4.67 8.74 2.64 4.83 0.34
2 - Array ad:
6.65 6.66 4.32 1.24 8.30 9.73 3.13

 


Related topics