Состав сооружений: решетки и песколовки: Решетки – это первое устройство в схеме очистных сооружений. Они представляют...
Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...
Топ:
Установка замедленного коксования: Чем выше температура и ниже давление, тем место разрыва углеродной цепи всё больше смещается к её концу и значительно возрастает...
Основы обеспечения единства измерений: Обеспечение единства измерений - деятельность метрологических служб, направленная на достижение...
Интересное:
Лечение прогрессирующих форм рака: Одним из наиболее важных достижений экспериментальной химиотерапии опухолей, начатой в 60-х и реализованной в 70-х годах, является...
Финансовый рынок и его значение в управлении денежными потоками на современном этапе: любому предприятию для расширения производства и увеличения прибыли нужны...
Влияние предпринимательской среды на эффективное функционирование предприятия: Предпринимательская среда – это совокупность внешних и внутренних факторов, оказывающих влияние на функционирование фирмы...
Дисциплины:
2019-09-26 | 234 |
5.00
из
|
Заказать работу |
Интерфейс IComparer определен в пространстве имен System.Collections. Он содержит один метод Compare, возвращающий результат сравнения двух объектов, переданных ему в качестве параметров:
interface IComparer
{
int Compare(object ob1, object ob2)
}
Принцип применения этого интерфейса состоит в том, что для каждого критерия сортировки объектов описывается небольшой вспомогательный класс, реализующий этот интерфейс. Объект этого класса передается в стандартный метод сортировки массива в качестве второго аргумента.
Пример сортировки массива объектов из предыдущего листинга по именам (свойство Name, класс SortByName) и количеству вооружений (свойство Ammo, класс SortByAmmo) приведен в листинге 2.
using System;
using System.Collections;
namespace ConsoleApplication1
{
class Monster
{
public Monster(int health, int ammo, string name)
{
this.health = health;
this.ammo = ammo;
this.name = name;
}
public int Ammo
{
get { return ammo; }
set
{
if (value > 0) ammo = value;
else ammo = 0;
}
}
public string Name
{
get { return name; }
}
virtual public void Passport()
{
Console.WriteLine("Monster {0} \t health = {1} ammo = {2}",
name, health, ammo);
}
public class SortByName: IComparer //
{
int IComparer.Compare(object ob1, object ob2)
{
Monster m1 = (Monster) ob1;
Monster m2 = (Monster) ob2;
return String.Compare(m1.Name, m2.Name);
}
}
public class SortByAmmo: IComparer //
{
int IComparer.Compare(object ob1, object ob2)
{
Monster m1 = (Monster) ob1;
Monster m2 = (Monster) ob2;
if (m1.Ammo > m2.Ammo) return 1;
if (m1.Ammo < m2.Ammo) return -1;
return 0;
}
}
string name;
int health, ammo;
}
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, "Маша");
Console.WriteLine("Сортировка по имени:");
Array.Sort(stado, new Monster.SortByName());
foreach (Monster elem in stado) elem.Passport();
Console.WriteLine("Сортировка по вооружению:");
Array.Sort(stado, new Monster.SortByAmmo());
foreach (Monster elem in stado) elem.Passport();
}
}
}
Листинг 2. Сортировка по двум критериям
Результат работы программы:
Сортировка по имени:
Monster Вася health = 50 ammo = 50
Monster Маша health = 40 ammo = 10
Monster Петя health = 80 ammo = 80
Сортировка по вооружению:
Monster Маша health = 40 ammo = 10
Monster Вася health = 50 ammo = 50
Monster Петя health = 80 ammo = 80
Перегрузка операций отношения
Если класс реализует интерфейс IComparable, его экземпляры можно сравнивать между собой на больше-меньше. Логично разрешить использовать для этого операции отношения, перегрузив их. Операции должны перегружаться парами: < и >, <= и >=, == и!=. Перегрузка операций обычно выполняется путем делегирования, то есть обращения к переопределенным методам CompareTo и Equals.
Обязательно
Если класс реализует интерфейс IComparable, требуется переопределить метод Equals и связанный с ним метод GetHashCode. Оба метода унаследованы от базового класса object.
В листинге 3 операции отношения перегружены для класса Monster. В качестве критерия сравнения объектов на больше-меньше выступает поле health, а при сравнении на равенство попарно сравниваются все поля объектов
using System;
namespace ConsoleApplication1
{
class Monster: IComparable
{
public Monster(int health, int ammo, string name)
{
this.health = health;
this.ammo = ammo;
this.name = name;
}
public override bool Equals(object obj)
{
if (obj == null || GetType()!= obj.GetType()) return false;
Monster temp = (Monster) obj;
return health == temp.health &&
ammo == temp.ammo &&
name == temp.name;
}
public override int GetHashCode()
{
return name.GetHashCode();
}
public static bool operator == (Monster a, Monster b)
{
return a.Equals(b);
}
public static bool operator!= (Monster a, Monster b)
{
return! a.Equals(b);
}
public static bool operator < (Monster a, Monster b)
{
return (a.CompareTo(b) < 0);
}
public static bool operator > (Monster a, Monster b)
{
return (a.CompareTo(b) > 0);
}
public static bool operator <= (Monster a, Monster b)
{
return (a.CompareTo(b) <= 0);
}
public static bool operator >= (Monster a, Monster b)
{
return (a.CompareTo(b) >= 0);
}
public int CompareTo(object obj)
{
Monster temp = (Monster) obj;
if (this.health > temp.health) return 1;
if (this.health < temp.health) return -1;
return 0;
}
string name;
int health, ammo;
}
class Class1
{ static void Main()
{
Monster Вася = new Monster(70, 80, "Вася");
Monster Петя = new Monster(80, 80, "Петя");
if (Вася > Петя) Console.WriteLine("Вася больше Пети");
else if (Вася == Петя) Console.WriteLine("Вася == Петя");
else Console.WriteLine("Вася меньше Пети");
}
}
}
Листинг 3. Перегрузка операций отношения
Результат работы программы:
Вася меньше Пети
Клонирование объектов
Клонирование — это создание копии объекта. Копия объекта называется клоном. Как известно, при присваивании одного объекта ссылочного типа другому копируется ссылка, а не сам объект. Если необходимо скопировать в другую область памяти поля объекта, можно воспользоваться методом MemberwiseClone, который любой объект наследует от класса object. При этом объекты, на которые указывают поля объекта, в свою очередь являющиеся ссылками, не копируются. Это называется поверхностным клонированием.
Для создания полностью независимых объектов необходимо глубокое клонирование, когда в памяти создается дубликат всего дерева объектов, то есть объектов, на которые ссылаются поля объекта, поля полей, и так далее. Алгоритм глубокого клонирования весьма сложен, поскольку требует рекурсивного обхода всех ссылок объекта и отслеживания циклических зависимостей.
Объект, имеющий собственные алгоритмы клонирования, должен объявляться как наследник интерфейса ICloneable и переопределять его единственный метод Clone. В листинге 9.4 приведен пример создания поверхностной копии объекта класса Monster с помощью метода MemberwiseClone, а также реализован интерфейс ICloneable. В демонстрационных целях в имя клона объекта добавлено слово "Клон".
using System;
namespace ConsoleApplication1
{
class Monster: ICloneable
{
public Monster(int health, int ammo, string name)
{
this.health = health;
this.ammo = ammo;
this.name = name;
}
public Monster ShallowClone() // поверхностная копия
{
return (Monster)this.MemberwiseClone();
}
public object Clone() // пользовательская копия
{
return new Monster(this.health, this.ammo, "Клон " + this.name);
}
virtual public void Passport()
{
Console.WriteLine("Monster {0} \t health = {1} ammo = {2}",
name, health, ammo);
}
string name;
int health, ammo;
}
class Class1
{ static void Main()
{
Monster Вася = new Monster(70, 80, "Вася");
Monster X = Вася;
Monster Y = Вася.ShallowClone();
Monster Z = (Monster)Вася.Clone();
...
}
}
}
Листинг 4. Клонирование объектов
Объект Х ссылается на ту же область памяти, что и объект Вася. Следовательно, если мы внесем изменения в один из этих объектов, это отразится на другом. Объекты Y и Z, созданные путем клонирования, обладают собственными копиями значений полей и независимы от исходного объекта.
Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...
Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...
Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!