Код, который вы создаете, будет лучше всего понятен, если он хорошо моделирует реальность.
Способ моделирования «A of B» заключается в использовании дженериков. Набор типов коробок, которые могут содержать один вид вещей, будет смоделирован как Коробка < T >
. Коробка, которая может содержать только игрушки, будет Коробка < Игрушка >
. Набор видов коробок, которые могут содержать один вид вещи, и эта вещь должна быть игрушка будет Коробка < T > где T: Toy
.
Пока так хорошо. Но понятие Toy < T >
ни к чему не относится в реальной жизни. У вас может быть коробка печенья или коробка игрушек, но у вас нет игрушки печенья, игрушки кукол или игрушки жирафов. Понятие «игрушка» не имеет никакого смысла, поэтому не моделируют его .
Более разумной вещью для моделирования было бы "существует общий класс вещей, называемых игрушками. Нет ничего, что было бы просто игрушкой; каждая игрушка - это более конкретный вид игрушки. Мяч - это игрушка. Кукла - это игрушка. Итак, модель, что:
abstract class Toy {}
class Doll : Toy {}
class Ball : Toy {}
Вы сказали
Я хочу, чтобы Игрушка была родовой и принять аргумент при создании экземпляра, потому что Игрушка также должна иметь Список в качестве члена.
Почему? Игрушка не имеет списка вещей . Так что не смоделируй это. Скорее коробка логически моделируется как список игрушек, которые находятся внутри коробки. (Или, поскольку коробка обычно не применяет заказ, а коробка содержит только уникальные игрушки, возможно, набор игрушек был бы лучше.)
Я хочу иметь возможность создавать игрушки с множеством различных типов и затем вставлять их в коробку с другим указанным типом.
OK. Таким образом, операция Box < T >
является недействительной Insert (T предмета)
. Можно положить игрушку в ящик игрушек, можно положить куклу в ящик кукол, но нельзя положить шар в ящик кукол.
Затем я хотел бы иметь возможность добавлять коробки вместе возвращая ящик с наибольшим типом.
Необходимо более тщательно определить «самый большой тип». Если добавить коробку с куклами в коробку с мячами, то явно результатом не станет ни коробка с мячами, ни коробка с куклами. В результате получается коробка игрушек.
Вот как бы я это смоделировал. У нас уже есть иерархия игрушек. Я бы продолжил, сказав, что коробка Т реализована как набор ее содержимого, и предоставляет последовательность ее содержимого.
// Haven't actually compiled this.
class Box<T> : IEnumerable<T>
{
private HashSet<T> set = new HashSet<T>();
public Insert(T item) { set.Add(item); }
public IEnumerator<T> GetEnumerator() { return set.GetEnumerator(); }
public IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
Пока все очень скучно. Теперь мы подходим к интересной части. Это хорошо работает только в C # 4 .
public static Box<T> MergeBoxes(IEnumerable<T> box1, IEnumerable<T> box2)
{
Box<T> box = new Box<T>();
foreach(T item in box1) box.Insert(item);
foreach(T item in box2) box.Insert(item);
return box;
}
}
Теперь вы можете сказать
Box<Doll> dollbox = new Box<Doll>() { new Doll() };
Box<Ball> ballbox = new Box<Ball>() { new Ball() };
Box<Toy> toybox2 = Box<Toy>.MergeBoxes(ballbox, dollbox);
Результатом слияния коробки кукол с коробкой шаров является коробка игрушек.
Этот последний бит работает только потому, что IEnumerable < T >
является ковариантным в C # 4. В C # 3 это было бы сложнее получить право; вам придется сделать что-то вроде:
Box<Toy> toybox2 = Box<Toy>.MergeBoxes(ballbox.Cast<Toy>(), dollbox.Cast<Toy>());
Имеет ли это смысл?
-121--2776780-Там, к сожалению, не так много - мир .NET, похоже, страдает от нехватки хороших математических библиотек с открытым исходным кодом. Лучшей легкодоступной коммерческой альтернативой является, вероятно, Ceometric's G # , который не является ни свободным, ни открытым исходным кодом.
Библиотека AFORGENET Первоначально предназначена для обработки изображений / компьютерного видения / машинного обучения AI, имеет ли у кого-нибудь хорошие функции, которые могут вам помочь! http://www.aforgenet.com/framework/