, у второго - Person. Все работает прекрасно. Вот результаты вычислений по этой процедуре: Как справиться с арифметикой Представьте себе, что мы хотим иметь специализированный вариант нашего списка, элементы которого допускали бы операцию сложения и одно из полей которого сохраняло бы сумму всех элементов, добавленных в список. Как задать соответствующее ограничение на класс? Как уже говорилось, наличие ограничения операции, где можно было бы указать, что над элементами определена операция +, решало бы проблему. Но такого типа ограничений нет. Хуже того, нет и интерфейса INumeric, аналогичного IComparable, определяющего метод сложения Add. Так что нам не может помочь и ограничение наследования. Вот один из возможных выходов, предлагаемых в такой ситуации. Стратегия следующая: определим абстрактный универсальный класс Calc с методами, выполняющими вычисления. Затем создадим конкретизированных потомков этого класса. В классе, задающем список с суммированием, введем поле класса Calc. При создании экземпляров класса будем передавать фактические типы ключа и элементов, а также соответствующий калькулятор, но уже не как тип, а как аргумент конструктора класса. Этот калькулятор, согласованный с типом элементов, и будет выполнять нужные вычисления. Давайте приступим к реализации этой стратегии. Начнем с определения класса Calc: public abstract class Calc<T> { public abstract T Add(T a, T b); public abstract T Sub(T a, T b); public abstract T Mult(T a, T b); public abstract T Div(T a, T b); } Наш абстрактный универсальный класс определяет четыре арифметические операции. Давайте построим трех его конкретизированных потомков: public class IntCalc : Calc<int> { public override int Add(int a, int b) { return (a + b);} public override int Sub(int a, int b) { return (a - b);} public override int Mult(int a, int b) { return (a * b);} |