C#. Узагальнені методи в класах

Узагальнені методи в класах. Синтаксис оголошення. Способи виклику

Перед вивченням даної теми рекомендується ознайомитись з наступною темою:


Зміст


Пошук на інших ресурсах:




1. Поняття узагальненого методу. Синтаксис оголошення узагальненого методу, що отримує параметрами декілька типів T1, T2, …, TN

У програмах на C# допускається оголошувати узагальнені методи. Узагальнені методи можуть бути оголошені в наступних елементах мови:

  • класах;
  • структурах;
  • інтерфейсах.

Розглянемо синтаксис оголошення узагальненого методу на прикладі класу. У неузагальненому класі узагальнений метод може бути оголошений за наступною загальною формою:

class ClassName
{
  ...

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

  ...
}

тут

  • ClassName – ім’я класу в якому оголошується узагальнений метод;
  • MethodName – ім’я узагальненого методу;
  • T1, T2, …, TN – імена типів, якими оперує узагальнений метод;
  • parameters_list – список параметрів, які отримує узагальнений метод. У списку параметрів допускається використання типів T1, T2, …, TN.

Якщо метод використовує один параметр типу T, то оголошення цього методу в класі буде простішим

class ClassName
{
  ...

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

  ...
}

Для структур (struct) та інтерфейсів (interface) оголошення узагальнених методів таке саме.

 

2. Синтаксис виклику узагальненого методу. Способи виклику

Якщо в класі оголошено узагальнений метод, який отримує параметром деякий тип T

class ClassName
{
  ...

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

  ...
}

то в екземплярі класу цей метод може бути викликаний наступними способами.

Спосіб 1. Виклик без явно заданого аргументу типу. У цьому випадку синтаксис виклику методу з іменем MethodName() без явно заданого аргументу типу має вигляд:

obj.MethodName(parameters)

тут

  • obj – екземпляр класу, в якому оголошується метод MethodName();
  • parameters – список параметрів методу.

Спосіб 2. Виклик з явно заданим аргументом типу. Синтаксис виклику наступний:

obj.MethodName<Type>(parameters)

тут

  • obj – екземпляр класу з оголошеним методом MethodName();
  • Type – назва типу, що виступає в ролі аргументу типу;
  • parameters – список параметрів методу.

Приклад. Оголошується клас Info з узагальненим методом Print(). Метод Print() отримує параметром деякий тип TT а також два параметри param1 та param2. Параметр param1 є типу TT. Параметр param2 є типу int і оголошується в демонстраційних цілях. У функції main() відбувається виклик методу Print() різними способами.

using System;

namespace ConsoleApp19
{
  // Клас, в якому оголошується узагальнений метод Print
  class Info
  {
    // Узагальнений метод, що отримує параметром тип TT
    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)
    {
      // Екземпляр класу MyClass
      Info mc = new Info();

      // 1. Виклик без явно заданого параметру типу
      // 1.1. Виклик з параметром типу string
      mc.Print("String", 23);

      // 1.2. Виклик з параметром типу char
      mc.Print('F', 330);

      // 2. Виклик з явно заданим параметром типу
      // 2.1. Виклик з явно заданим типом double
      mc.Print<double>(2.88, 33);

      // 2.2. Виклик з явно заданим типом string
      mc.Print<string>("String", 23);

      Console.ReadKey();
    }
  }
}

Результат виконання програми

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

 

3. Приклад оголошення та використання узагальненого методу в класі

Нехай у класі потрібно реалізувати узагальнений метод Print(), що виводить інформацію про тип T та значення цього типу. Програмний код такого класу та методу може бути, наприклад, таким

using System;

namespace ConsoleApp19
{
  // Неузагальнений клас, що містить узагальнений метод Print()
  class PrintInfo
  {
    // Узагальнений метод 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)
    {
      // Демонстрація використання узагальненого методу Print<T>()
      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();
    }
  }
}

Результат виконання програми

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

 

4. Приклад оголошення та використання узагальненого методу в інтерфейсі. Метод отримує два параметри типу T1, T2

Умова задачі. Оголосити неузагальнений інтерфейс IInfo, в якому оголошується єдиний метод GetInfo<T1, T2>(), який отримує два параметри типів T1, T2. Метод повинен повертати інформацію про значення та назви типів параметрів

Інтерфейс IInfo потрібно реалізувати в неузагальненому класі CInfo.

Продемонструвати роботу методу GetInfo<T1, T2>() у функції main() для різних типів заповнювачів.

Розв’язок.

using System;

namespace ConsoleApp19
{
  // Неузагальнений інтерфейс.
  // В інтерфейсі оголошується метод, що отримує два параметри типу T1, T2
  interface IInfo
  {
    // Метод, що отримує два параметри типу
    string GetInfo<T1, T2>(T1 value1, T2 value2);
  }

  // Неузагальнений клас, що реалізує інтерфейс IInfo
  class CInfo : IInfo
  {
    // Узагальнений метод GetInfo<T1, T2>().
    // Метод повертає інформаційний рядок про типи T1, T2.
    public string GetInfo<T1, T2>(T1 value1, T2 value2)
    {
      string s = ""; // Рядок результату

      // Отримати інформацію про тип T1
      Type tp1 = typeof(T1);
      s = "Type1: " + tp1.FullName + ", ";
      s += "value1: " + Convert.ToString(value1) + ". ";

      // Отримати інформацію про тип T2
      Type tp2 = typeof(T2);
      s += "Type2: " + tp2.FullName + ", ";
      s += "value2: " + Convert.ToString(value2) + ".";

      return s;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Демонстрація використання узагальненого методу GetInfo<T1, T2>()
      // Створити екземпляр класу CInfo
      IInfo info1 = new CInfo();

      // Викликати метод GetInfo<T1, T2>() для різних типів заповнювачів
      // <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();
    }
  }
}

Результат виконання програми

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

 


Зв’язані теми