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.

 


Связанные темы