Стандартные интерфейсы .NET: IComparable, IClonable, IEnumerable. Примеры реализации.
В библиотеке классов .NET определено множество стандартных интерфейсов, задающих желаемое поведение объектов. Например, интерфейс IComparable задает метод сравнения объектов на «больше-меньше», что позволяет выполнять их сортировку.
Реализация интерфейсов IEnumerable и IEnumerator дает возможность просматривать содержимое объекта с помощью foreach , а реализация интерфейса ICloneable — клонировать объекты.
Стандартные интерфейсы поддерживаются многими стандартными классами библиотеки. Например, работа с массивами с помощью foreach возможна потому, что тип Array реализует интерфейсы IEnumerable и IEnumerator .
Можно создавать и собственные классы, поддерживающие стандартные интерфейсы, что позволит использовать объекты этих классов стандартными способами.
Сравнение объектов
Интерфейс IComparable определен в пространстве имен System. Он содержит всего один метод CompareTo, возвращающий результат сравнения двух объектов — текущего и переданного ему в качестве параметра:
interface IComparable
{
int CompareTo( object obj )
}
Метод должен возвращать:
0, если текущий объект и параметр равны;
отрицательное число, если текущий объект меньше параметра;
положительное число, если текущий объект больше параметра.
- 0, если текущий объект и параметр равны; отрицательное число, если текущий объект меньше параметра; положительное число, если текущий объект больше параметра.
Пример реализации интерфейса
class Monster : IComparable
{ public int CompareTo ( object obj ) // реализация
// интерфейса
{ Monster temp = (Monster) obj;
if ( this.health temp.health ) return 1;
if ( this.health
return 0; }
... }
class Class1
{ static void Main()
{ const int n = 3;
Monster[] stado = new Monster[n];
stado[0] = new Monster( 50, 50, " Вася " );
stado[1] = new Monster( 80, 80, " Петя " );
stado[2] = new Monster( 40, 10, " Маша " );
Array . Sort ( stado ); // сортировка стала возможной
}
}
Параметризованные интерфейсы
class Program {
class Elem : IComparable
{ string data;
int key;
...
public int CompareTo( Elem obj )
{ return key - obj.key ; }
}
static void Main(string[] args)
{
ListElem list = new List();
for ( int i = 0; i
list.Sort();
...
}
}
Стандартные коллекции построены на основе параметризованных (обобщенных) интерфейсов.
Они не требуют многократной упаковки-распаковки и сохраняют контроль типов.
Обычные интерфейсы оставлены для обратной совместимости.
Клонирование объектов
Клонирование — создание копии объекта. Копия объекта называется клоном.
a
a
a
b
b
b
a) присваивание
b = a
б) поверхностное клонирование
в) глубокое клонирование
7
При присваивании одного объекта ссылочного типа другому копируется ссылка, а не сам объект (рис. а ).
Если необходимо скопировать в другую область памяти поля объекта, можно воспользоваться методом MemberwiseClone , который объект наследует от класса object . При этом объекты, на которые указывают поля объекта, в свою очередь являющиеся ссылками, не копируются (рис. б ). Это называется поверхностным клонированием .
Для создания полностью независимых объектов необходимо глубокое клонирование , когда в памяти создается дубликат всего дерева объектов (рис. в ).
Алгоритм глубокого клонирования весьма сложен, поскольку требует рекурсивного обхода всех ссылок объекта и отслеживания циклических зависимостей.
Объект, имеющий собственные алгоритмы клонирования, должен объявляться как наследник интерфейса ICloneable и переопределять его единственный метод Clone .
7