Так что мне действительно нравятся структуры данных, и я работаю над библиотекой классов, которая по-разному реализует различные типы графиков. Один из камней преткновения, с которым я столкнулся, - это попытка легко объединить особенности различных типов графиков.
Для пояснения, скажем, у меня есть интерфейс с именем IGraph , где T - данные, которые содержит каждый узел. Теперь я также хочу иметь интерфейсы для IUndirectedGraph , IDigraph и IWeightedGraph , где E - это тип, используемый в качестве веса.
Я хотел бы иметь возможность предоставлять разные реализации одного и того же типа графа. Например, я хотел бы иметь возможность предоставить класс, который использует список смежности и класс, который использует матрицу смежности. Классы могут иметь несколько разные реализации определенных алгоритмов. В качестве простого примера, определение соседей данного объекта будет различным в каждой реализации.
Итак, допустим, у меня есть два объявления классов:
class WeightedAdjacencyListGraph<T,E> : IUndirectedGraph<T>, IWeightedGraph<T,E>
class WeightedAdjacencyMatrixGraph<T,E> : IUndirectedGraph<T>, IWeightedGraph<T,E>
Я бы хотел иметь возможность объявлять тип переменной, которая может хранить объекты обоих этих классов, но при этом сохранять функциональность, определенную во всех интерфейсах. По сути, я хочу иметь возможность объявлять тип переменной, например:
<IUndirectedGraph<object>+IWeightedGraph<object,double>> MyGraph = new WeightedAdjacencyListGraph<object,double>();
MyGraph = new WeightedAdjacencyMatrixGraph<object,double>();
Очевидно, что объявление типа переменной не является правильным синтаксисом C #, но что бы я здесь поместил? Нужно ли создавать новый интерфейс для каждой комбинации интерфейсов? Является ли мой дизайн в корне ошибочным, и если да, что я должен сделать, чтобы исправить его?
Редактировать: я решил создать разные пространства имен для ориентированных / ненаправленных графов и хранить общие интерфейсы (такие как IWeightedGraph ) в корневом пространстве имен. Затем я в основном создаю комбинированные интерфейсы, о которых я упоминал выше (которые также были отмечены в ответах). Я полагаю, что ориентированные / ненаправленные графы вряд ли будут иметь что-то общее, когда дело доходит до забавных алгоритмов.