C#. Generic methods in classes

Generic methods in classes. Declaration syntax. Methods call

Before exploring this topic, it is recommended that you familiarize yourself with the following topic:


Contents


Search other resources:




1. The concept of a generic method. Syntax for declaring a generic method that takes as parameters several types T1, T2, …, TN

In C# programs, it is allowed to declare generic methods. Generic methods can be declared in the following language elements:

  • class;
  • structure;
  • interface.

Let’s consider the syntax for declaring a generic method using a class as an example. In a non-generic class, a generic method can be declared with the following general form:

class ClassName
{
  ...

  return_type MethodName<T1, T2, ..., TN>(parameters_list)
  {
    ...
  }

  ...
}

here

  • ClassName The name of the class in which the generic method is declared;
  • MethodName – generic method name;
  • T1, T2, …, TN – the names of the types that the generic method operates on;
  • parameters_list – a list of parameters that the generic method receives. The types T1, T2, …, TN are allowed in the parameter list.

If the method uses one parameter of type T, then the declaration of this method in the class will be simpler

class ClassName
{
  ...

  return_type MethodName<T>(parameters_list)
  {
    ...
  }

  ...
}

For structures and interfaces, the declaration of generic methods is the same.

 

2. The syntax for calling a generic method. Calling methods

If a generic method is declared in the class that receives as a parameter some type T

class ClassName
{
  ...

  public return_type MethodName<T>(parameters_list)
  {
    ...
  }

  ...
}

then in an instance of a class, this method can be called in the following ways.

Way 1. Call without an explicit type argument. In this case, the syntax for calling a method named MethodName() without an explicitly specified type argument is:

obj.MethodName(parameters)

here

  • obj – an instance of the class in which the MethodName() method is declared;
  • parameters – list of method parameters.

Way 2. Call with an explicitly specified type argument. The syntax for the call is as follows:

obj.MethodName<Type>(parameters)

here

  • obj – an instance of a class with a declared method MethodName();
  • Type – a type name serving as a type argument;
  • parameters – list of method parameters.

Example.

The Info class is declared with a generic Print() method. The Print() method receives as a parameter some type TT as well as two parameters param1 and param2. The param1 parameter is of type TT. The param2 parameter is of type int and is declared for demonstration purposes. In the main() function, the Print() method is called in various ways.

using System;

namespace ConsoleApp19
{
  // The class in which the generic Print() method is declared
  class Info
  {
    // Generic method that takes TT type as a parameter
    public void Print<TT>(TT param1, int param2)
    {
      Console.WriteLine("param1 = {0}", param1);
      Console.WriteLine("param2 = {0}", param2);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // The instance of MyClass class
      Info mc = new Info();

      // 1. Call without an explicitly specified type parameter
      // 1.1. Call with a parameter of type string
      mc.Print("String", 23);

      // 1.2. Call with a parameter of type char
      mc.Print('F', 330);

      // 2. Call with an explicitly specified type parameter
      // 2.1. Call with an explicitly specified type double
      mc.Print<double>(2.88, 33);

      // 2.2. Call with explicitly specified type string
      mc.Print<string>("String", 23);

      Console.ReadKey();
    }
  }
}

The result of the program

param1 = String
param2 = 23
param1 = F
param2 = 330
param1 = 2.88
param2 = 33
param1 = String
param2 = 23

 

3. An example of declaring and using a generic method in a class

Suppose a class needs to implement a generic Print() method that prints information about the type T and the value of this type. The program code of such a class and method can be, for example, the following

using System;

namespace ConsoleApp19
{
  // A non-generic class containing a generic Print() method
  class PrintInfo
  {
    // Generic method Print<T>()
    public void Print<T>(T value)
    {
      Type tp = typeof(T);
      Console.Write("Type: {0},   ", tp.Name);
      Console.WriteLine("value = {0}", value);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Demonstration of using the generic Print<T>() method
      PrintInfo pi = new PrintInfo();
      pi.Print<double>(25.88);
      pi.Print<int>(1232);
      pi.Print<char>('c');
      pi.Print<bool>(false);
      pi.Print<string>("BestProg");
      Console.ReadKey();
    }
  }
}

The result of the program

Type: Double,   value = 25.88
Type: Int32,   value = 1232
Type: Char,   value = c
Type: Boolean,   value = False
Type: String,   value = BestProg

 

4. An example of declaring and using a generic method in an interface. The method receives two parameters of types T1, T2

Task.

Declare a non-generic IInfo interface, which declares a single GetInfo<T1, T2>() method that receives two parameters of types T1, T2. The method must return information about the value and name of the parameter types.

The IInfo interface must be implemented in the non-generic CInfo class. Demonstrate how the GetInfo<T1, T2>() method works in the main() function for different types of placeholders.

Solution.

using System;

namespace ConsoleApp19
{
  // Non-generic interface.
  // The interface declares a method that receives two parameters of types T1, T2
  interface IInfo
  {
    // A method that takes two type parameters
    string GetInfo<T1, T2>(T1 value1, T2 value2);
  }

  // Non-generic class that implements the Info interface
  class CInfo : IInfo
  {
    // Generic method GetInfo<T1, T2>().
    // The method returns an information string about the types T1, T2.
    public string GetInfo<T1, T2>(T1 value1, T2 value2)
    {
      string s = ""; // Result string

      // Get information about type T1
      Type tp1 = typeof(T1);
      s = "Type1: " + tp1.FullName + ", ";
      s += "value1: " + Convert.ToString(value1) + ". ";

      // Get information about type T2
      Type tp2 = typeof(T2);
      s += "Type2: " + tp2.FullName + ", ";
      s += "value2: " + Convert.ToString(value2) + ".";

      return s;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Demonstration of using the generic GetInfo<T1, T2>() method
      // Create an instance of the CInfo class
      IInfo info1 = new CInfo();

      // Call GetInfo<T1, T2>() method for different placeholder types
      // <int, double>
      string str = info1.GetInfo<int, double>(23, 8.883);
      Console.WriteLine(str);

      // <char, float>
      str = info1.GetInfo<char, float>('a', 23.55f);
      Console.WriteLine(str);

      Console.ReadKey();
    }
  }
}

The result of the program

Type1: System.Int32, value1: 23.   Type2: System.Double, value2: 8.883.
Type1: System.Char, value1: a.   Type2: System.Single, value2: 23.55.

 


Related topics